Example #1
0
            /// <summary>
            /// [0.18.0]
            /// </summary>
            public static void DrawFields <T>(ref T container, ModEntry mod, DrawFieldMask defaultMask, Action onChange = null) where T : new()
            {
                object obj     = container;
                var    changed = Draw(obj, typeof(T), mod, defaultMask);

                if (changed)
                {
                    container = (T)obj;
                    if (onChange != null)
                    {
                        try
                        {
                            onChange();
                        }
                        catch (Exception e)
                        {
                            mod.Logger.LogException(e);
                        }
                    }
                }
            }
Example #2
0
 public DrawFieldsAttribute(DrawFieldMask Mask)
 {
     this.Mask = Mask;
 }
Example #3
0
            private static bool Draw(object container, Type type, ModEntry mod, DrawFieldMask defaultMask)
            {
                bool          changed = false;
                var           options = new List <GUILayoutOption>();
                DrawFieldMask mask    = defaultMask;

                foreach (DrawFieldsAttribute attr in type.GetCustomAttributes(typeof(DrawFieldsAttribute), false))
                {
                    mask = attr.Mask;
                }
                var fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);

                foreach (var f in fields)
                {
                    DrawAttribute a          = new DrawAttribute();
                    var           attributes = f.GetCustomAttributes(typeof(DrawAttribute), false);
                    if (attributes.Length > 0)
                    {
                        foreach (DrawAttribute a_ in attributes)
                        {
                            a        = a_;
                            a.Width  = a.Width != 0 ? Scale(a.Width) : 0;
                            a.Height = a.Height != 0 ? Scale(a.Height) : 0;
                        }

                        if (a.Type == DrawType.Ignore)
                        {
                            continue;
                        }

                        //if (!string.IsNullOrEmpty(a.DependsOn))
                        //{
                        //    var field = type.GetField(a.DependsOn, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                        //    if (field == null)
                        //    {

                        //    }
                        //    else
                        //    {
                        //        var value = field.GetValue(container);
                        //    }

                        //}
                    }
                    else
                    {
                        if ((mask & DrawFieldMask.OnlyDrawAttr) == 0 && ((mask & DrawFieldMask.SkipNotSerialized) == 0 || !f.IsNotSerialized) &&
                            ((mask & DrawFieldMask.Public) > 0 && f.IsPublic ||
                             (mask & DrawFieldMask.Serialized) > 0 && f.GetCustomAttributes(typeof(SerializeField), false).Length > 0 ||
                             (mask & DrawFieldMask.Public) == 0 && (mask & DrawFieldMask.Serialized) == 0))
                        {
                            foreach (RangeAttribute a_ in f.GetCustomAttributes(typeof(RangeAttribute), false))
                            {
                                a.Type = DrawType.Slider;
                                a.Min  = a_.min;
                                a.Max  = a_.max;
                                break;
                            }
                            foreach (HeaderAttribute a_ in f.GetCustomAttributes(typeof(HeaderAttribute), false))
                            {
                                a.Label = a_.header;
                                break;
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    foreach (SpaceAttribute a_ in f.GetCustomAttributes(typeof(SpaceAttribute), false))
                    {
                        GUILayout.Space(Scale((int)a_.height));
                    }

                    var fieldName = string.IsNullOrEmpty(a.Label) ? f.Name : a.Label;

                    if (f.FieldType.IsClass || f.FieldType.IsValueType && !f.FieldType.IsPrimitive && !f.FieldType.IsEnum && !Array.Exists(specialTypes, x => x == f.FieldType))
                    {
                        defaultMask = mask;
                        foreach (DrawFieldsAttribute attr in f.GetCustomAttributes(typeof(DrawFieldsAttribute), false))
                        {
                            defaultMask = attr.Mask;
                        }
                        var horizontal = f.GetCustomAttributes(typeof(HorizontalAttribute), false).Length > 0;
                        if (horizontal)
                        {
                            GUILayout.BeginHorizontal();
                        }
                        GUILayout.Label($"{fieldName}", GUILayout.ExpandWidth(false));
                        var val = f.GetValue(container);
                        if (Draw(val, f.FieldType, mod, defaultMask))
                        {
                            changed = true;
                            f.SetValue(container, val);
                        }
                        if (horizontal)
                        {
                            GUILayout.EndHorizontal();
                        }
                        continue;
                    }

                    options.Clear();
                    if (a.Type == DrawType.Auto)
                    {
                        if (Array.Exists(fieldTypes, x => x == f.FieldType))
                        {
                            a.Type = DrawType.Field;
                        }
                        else if (Array.Exists(toggleTypes, x => x == f.FieldType))
                        {
                            a.Type = DrawType.Toggle;
                        }
                        else if (f.FieldType.IsEnum)
                        {
                            if (f.GetCustomAttributes(typeof(FlagsAttribute), false).Length == 0)
                            {
                                a.Type = DrawType.PopupList;
                            }
                        }
                    }

                    if (a.Type == DrawType.Field)
                    {
                        if (!Array.Exists(fieldTypes, x => x == f.FieldType))
                        {
                            mod.Logger.Error($"Type {f.FieldType} can't be drawed as {DrawType.Field}");
                            break;
                        }

                        options.Add(a.Width != 0 ? GUILayout.Width(a.Width) : GUILayout.Width(Scale(100)));
                        options.Add(a.Height != 0 ? GUILayout.Height(a.Height) : GUILayout.Height(Scale((int)drawHeight)));
                        if (f.FieldType == typeof(Vector2))
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                            GUILayout.Space(Scale(5));
                            var vec = (Vector2)f.GetValue(container);
                            if (DrawVector(ref vec, null, options.ToArray()))
                            {
                                f.SetValue(container, vec);
                                changed = true;
                            }
                            GUILayout.FlexibleSpace();
                            GUILayout.EndHorizontal();
                        }
                        else if (f.FieldType == typeof(Vector3))
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                            GUILayout.Space(Scale(5));
                            var vec = (Vector3)f.GetValue(container);
                            if (DrawVector(ref vec, null, options.ToArray()))
                            {
                                f.SetValue(container, vec);
                                changed = true;
                            }
                            GUILayout.FlexibleSpace();
                            GUILayout.EndHorizontal();
                        }
                        else if (f.FieldType == typeof(Vector4))
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                            GUILayout.Space(Scale(5));
                            var vec = (Vector4)f.GetValue(container);
                            if (DrawVector(ref vec, null, options.ToArray()))
                            {
                                f.SetValue(container, vec);
                                changed = true;
                            }
                            GUILayout.FlexibleSpace();
                            GUILayout.EndHorizontal();
                        }
                        else if (f.FieldType == typeof(Color))
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                            GUILayout.Space(Scale(5));
                            var vec = (Color)f.GetValue(container);
                            if (DrawColor(ref vec, null, options.ToArray()))
                            {
                                f.SetValue(container, vec);
                                changed = true;
                            }
                            GUILayout.FlexibleSpace();
                            GUILayout.EndHorizontal();
                        }
                        else
                        {
                            GUILayout.BeginHorizontal();
                            GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                            GUILayout.Space(Scale(5));
                            var val = f.GetValue(container).ToString();
                            if (a.Precision >= 0 && (f.FieldType == typeof(float) || f.FieldType == typeof(double)))
                            {
                                if (Double.TryParse(val, System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out var num))
                                {
                                    val = num.ToString($"f{a.Precision}");
                                }
                            }
                            var result = f.FieldType == typeof(string) ? GUILayout.TextField(val, a.MaxLength, options.ToArray()) : GUILayout.TextField(val, options.ToArray());
                            GUILayout.EndHorizontal();
                            if (result != val)
                            {
                                if (string.IsNullOrEmpty(result))
                                {
                                    if (f.FieldType != typeof(string))
                                    {
                                        result = "0";
                                    }
                                }
                                else
                                {
                                    if (Double.TryParse(result, System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out var num))
                                    {
                                        num    = Math.Max(num, a.Min);
                                        num    = Math.Min(num, a.Max);
                                        result = num.ToString();
                                    }
                                    else
                                    {
                                        result = "0";
                                    }
                                }
                                f.SetValue(container, Convert.ChangeType(result, f.FieldType));
                                changed = true;
                            }
                        }
                    }
                    else if (a.Type == DrawType.Slider)
                    {
                        if (!Array.Exists(sliderTypes, x => x == f.FieldType))
                        {
                            mod.Logger.Error($"Type {f.FieldType} can't be drawed as {DrawType.Slider}");
                            break;
                        }

                        options.Add(a.Width != 0 ? GUILayout.Width(a.Width) : GUILayout.Width(Scale(200)));
                        options.Add(a.Height != 0 ? GUILayout.Height(a.Height) : GUILayout.Height(Scale((int)drawHeight)));
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                        GUILayout.Space(Scale(5));
                        var val = f.GetValue(container).ToString();
                        if (!Double.TryParse(val, System.Globalization.NumberStyles.Any, System.Globalization.NumberFormatInfo.InvariantInfo, out var num))
                        {
                            mod.Logger.Error($"Field {fieldName} can't be parsed as number");
                            break;
                        }
                        var fnum   = (float)num;
                        var result = GUILayout.HorizontalSlider(fnum, (float)a.Min, (float)a.Max, options.ToArray());
                        GUILayout.Space(Scale(5));
                        GUILayout.Label(result.ToString(), GUILayout.ExpandWidth(false), GUILayout.Height(Scale((int)drawHeight)));
                        GUILayout.EndHorizontal();
                        if (result != fnum)
                        {
                            if ((f.FieldType == typeof(float) || f.FieldType == typeof(double)) && a.Precision >= 0)
                            {
                                result = (float)Math.Round(result, a.Precision);
                            }
                            f.SetValue(container, Convert.ChangeType(result, f.FieldType));
                            changed = true;
                        }
                    }
                    else if (a.Type == DrawType.Toggle)
                    {
                        if (!Array.Exists(toggleTypes, x => x == f.FieldType))
                        {
                            mod.Logger.Error($"Type {f.FieldType} can't be drawed as {DrawType.Toggle}");
                            break;
                        }

                        options.Add(GUILayout.ExpandWidth(false));
                        options.Add(a.Height != 0 ? GUILayout.Height(a.Height) : GUILayout.Height(Scale((int)drawHeight)));
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                        var val    = (bool)f.GetValue(container);
                        var result = GUILayout.Toggle(val, "", options.ToArray());
                        GUILayout.EndHorizontal();
                        if (result != val)
                        {
                            f.SetValue(container, Convert.ChangeType(result, f.FieldType));
                            changed = true;
                        }
                    }
                    else if (a.Type == DrawType.ToggleGroup)
                    {
                        if (!f.FieldType.IsEnum || f.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0)
                        {
                            mod.Logger.Error($"Type {f.FieldType} can't be drawed as {DrawType.ToggleGroup}");
                            break;
                        }

                        options.Add(GUILayout.ExpandWidth(false));
                        options.Add(a.Height != 0 ? GUILayout.Height(a.Height) : GUILayout.Height(Scale((int)drawHeight)));
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                        GUILayout.Space(Scale(5));
                        var values = Enum.GetNames(f.FieldType);
                        var val    = (int)f.GetValue(container);

                        if (ToggleGroup(ref val, values, null, options.ToArray()))
                        {
                            var v = Enum.Parse(f.FieldType, values[val]);
                            f.SetValue(container, v);
                            changed = true;
                        }
                        GUILayout.EndHorizontal();
                    }
                    else if (a.Type == DrawType.PopupList)
                    {
                        if (!f.FieldType.IsEnum || f.GetCustomAttributes(typeof(FlagsAttribute), false).Length > 0)
                        {
                            mod.Logger.Error($"Type {f.FieldType} can't be drawed as {DrawType.PopupList}");
                            break;
                        }

                        options.Add(GUILayout.ExpandWidth(false));
                        options.Add(a.Height != 0 ? GUILayout.Height(a.Height) : GUILayout.Height(Scale((int)drawHeight)));
                        GUILayout.BeginHorizontal();
                        GUILayout.Label(fieldName, GUILayout.ExpandWidth(false));
                        GUILayout.Space(Scale(5));
                        var values = Enum.GetNames(f.FieldType);
                        var val    = (int)f.GetValue(container);
                        if (PopupToggleGroup(ref val, values, null, options.ToArray()))
                        {
                            var v = Enum.Parse(f.FieldType, values[val]);
                            f.SetValue(container, v);
                            changed = true;
                        }
                        GUILayout.EndHorizontal();
                    }
                }
                return(changed);
            }