private void DrawUnknownField(SettingEntryBase setting, int rightColumnWidth)
        {
            // Try to use user-supplied converters
            if (setting.ObjToStr != null && setting.StrToObj != null)
            {
                var text   = setting.ObjToStr(setting.Get());
                var result = GUILayout.TextField(text, GUILayout.MaxWidth(rightColumnWidth));
                if (result != text)
                {
                    setting.Set(setting.StrToObj(result));
                }
                return;
            }

            // Fall back to slow/less reliable method
            var value = setting.Get()?.ToString() ?? "NULL";

            if (CanCovert(value, setting.SettingType))
            {
                var result = GUILayout.TextField(value, GUILayout.MaxWidth(rightColumnWidth));
                if (result != value)
                {
                    setting.Set(Convert.ChangeType(result, setting.SettingType));
                }
            }
            else
            {
                GUILayout.TextArea(value, GUILayout.MaxWidth(rightColumnWidth));
            }

            GUILayout.FlexibleSpace();
        }
        private static void DrawDefaultButton(SettingEntryBase setting)
        {
            if (setting.HideDefaultButton)
            {
                return;
            }

            GUI.backgroundColor = _widgetBackgroundColor.Value;

            bool DrawDefaultButton()
            {
                GUILayout.Space(5);
                return(GUILayout.Button(_resetSettingText.Value, buttonStyle, GUILayout.ExpandWidth(false)));
            }

            if (setting.DefaultValue != null)
            {
                if (DrawDefaultButton())
                {
                    setting.Set(setting.DefaultValue);
                }
            }
            else if (setting.SettingType.IsClass)
            {
                if (DrawDefaultButton())
                {
                    setting.Set(null);
                }
            }
        }
        private static void DrawRangeField(SettingEntryBase setting)
        {
            var value      = setting.Get();
            var converted  = (float)Convert.ToDouble(value);
            var leftValue  = (float)Convert.ToDouble(setting.AcceptableValueRange.Key);
            var rightValue = (float)Convert.ToDouble(setting.AcceptableValueRange.Value);

            var result = GUILayout.HorizontalSlider(converted, leftValue, rightValue, GUILayout.ExpandWidth(true));

            if (Math.Abs(result - converted) > Mathf.Abs(rightValue - leftValue) / 1000)
            {
                var newValue = Convert.ChangeType(result, setting.SettingType);
                setting.Set(newValue);
            }

            if (setting.ShowRangeAsPercent == true)
            {
                DrawCenteredLabel(
                    Mathf.Round(100 * Mathf.Abs(result - leftValue) / Mathf.Abs(rightValue - leftValue)) + "%",
                    GUILayout.Width(50));
            }
            else
            {
                var strVal    = value.ToString();
                var strResult = GUILayout.TextField(strVal, GUILayout.Width(50));
                if (strResult != strVal)
                {
                    var resultVal        = (float)Convert.ToDouble(strResult);
                    var clampedResultVal = Mathf.Clamp(resultVal, leftValue, rightValue);
                    setting.Set(Convert.ChangeType(clampedResultVal, setting.SettingType));
                }
            }
        }
        private void DrawUnknownField(SettingEntryBase setting, int rightColumnWidth)
        {
            // Try to use user-supplied converters
            if (setting.ObjToStr != null && setting.StrToObj != null)
            {
                var text   = setting.ObjToStr(setting.Get()).AppendZeroIfFloat(setting.SettingType);
                var result = GUILayout.TextField(text, BepInExPlugin.textStyle, GUILayout.MaxWidth(rightColumnWidth));
                if (result != text)
                {
                    setting.Set(setting.StrToObj(result));
                }
            }
            else
            {
                // Fall back to slow/less reliable method
                var rawValue = setting.Get();
                var value    = rawValue == null ? "NULL" : rawValue.ToString().AppendZeroIfFloat(setting.SettingType);
                if (CanCovert(value, setting.SettingType))
                {
                    var result = GUILayout.TextField(value, BepInExPlugin.textStyle, GUILayout.MaxWidth(rightColumnWidth));
                    if (result != value)
                    {
                        setting.Set(Convert.ChangeType(result, setting.SettingType, CultureInfo.InvariantCulture));
                    }
                }
                else
                {
                    GUILayout.TextArea(value, BepInExPlugin.textStyle, GUILayout.MaxWidth(rightColumnWidth));
                }
            }

            // When using MaxWidth the width will always be less than full window size, use this to fill this gap and push the Reset button to the right edge
            GUILayout.FlexibleSpace();
        }
        private static void DrawColor(SettingEntryBase obj)
        {
            var setting = (Color)obj.Get();

            if (!_colorCache.TryGetValue(obj, out var cacheEntry))
            {
                cacheEntry = new ColorCacheEntry {
                    Tex = new Texture2D(40, 10, TextureFormat.ARGB32, false), Last = setting
                };
                cacheEntry.Tex.FillTexture(setting);
                _colorCache[obj] = cacheEntry;
            }

            GUILayout.Label("R", BepInExPlugin.labelStyle, GUILayout.ExpandWidth(false));
            setting.r = GUILayout.HorizontalSlider(setting.r, 0f, 1f, GUILayout.ExpandWidth(true));
            GUILayout.Label("G", BepInExPlugin.labelStyle, GUILayout.ExpandWidth(false));
            setting.g = GUILayout.HorizontalSlider(setting.g, 0f, 1f, GUILayout.ExpandWidth(true));
            GUILayout.Label("B", BepInExPlugin.labelStyle, GUILayout.ExpandWidth(false));
            setting.b = GUILayout.HorizontalSlider(setting.b, 0f, 1f, GUILayout.ExpandWidth(true));
            GUILayout.Label("A", BepInExPlugin.labelStyle, GUILayout.ExpandWidth(false));
            setting.a = GUILayout.HorizontalSlider(setting.a, 0f, 1f, GUILayout.ExpandWidth(true));

            GUILayout.Space(4);

            if (setting != cacheEntry.Last)
            {
                obj.Set(setting);
                cacheEntry.Tex.FillTexture(setting);
                cacheEntry.Last = setting;
            }

            GUILayout.Label(cacheEntry.Tex, BepInExPlugin.labelStyle, GUILayout.ExpandWidth(false));
        }
        public void DrawSettingValue(SettingEntryBase setting)
        {
            GUI.backgroundColor = BepInExPlugin._widgetBackgroundColor.Value;

            if (setting.CustomDrawer != null)
            {
                setting.CustomDrawer(setting is ConfigSettingEntry newSetting ? newSetting.Entry : null);
            }
            else if (setting.ShowRangeAsPercent != null && setting.AcceptableValueRange.Key != null)
            {
                DrawRangeField(setting);
            }
            else if (setting.AcceptableValues != null)
            {
                DrawListField(setting);
            }
            else if (setting.SettingType.IsEnum)
            {
                if (setting.SettingType.GetCustomAttributes(typeof(FlagsAttribute), false).Any())
                {
                    DrawFlagsField(setting, Enum.GetValues(setting.SettingType), _instance.RightColumnWidth);
                }
                else
                {
                    DrawComboboxField(setting, Enum.GetValues(setting.SettingType), _instance.DefaultWindowRect.yMax);
                }
            }
            else
            {
                DrawFieldBasedOnValueType(setting);
            }
        }
Exemple #7
0
        public void DrawKeyboardShortcut(SettingEntryBase setting)
        {
            var value     = setting.Get();
            var isOldType = value is KeyboardShortcut;

            GUILayout.BeginHorizontal();
            {
                if (CurrentKeyboardShortcutToSet == setting)
                {
                    GUILayout.Label("Press any key combination", GUILayout.ExpandWidth(true));
                    GUIUtility.keyboardControl = -1;

                    foreach (var key in KeysToCheck)
                    {
                        if (Input.GetKeyUp(key))
                        {
                            if (isOldType)
                            {
                                setting.Set(new KeyboardShortcut(key, KeysToCheck.Where(Input.GetKey).ToArray()));
                            }
                            else
                            {
                                setting.Set(new BepInEx.Configuration.KeyboardShortcut(key, KeysToCheck.Where(Input.GetKey).ToArray()));
                            }
                            CurrentKeyboardShortcutToSet = null;
                            break;
                        }
                    }

                    if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
                    {
                        CurrentKeyboardShortcutToSet = null;
                    }
                }
                else
                {
                    if (GUILayout.Button(value.ToString(), GUILayout.ExpandWidth(true)))
                    {
                        CurrentKeyboardShortcutToSet = setting;
                    }

                    if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
                    {
                        if (isOldType)
                        {
                            setting.Set(new KeyboardShortcut());
                        }
                        else
                        {
                            setting.Set(BepInEx.Configuration.KeyboardShortcut.Empty);
                        }
                        CurrentKeyboardShortcutToSet = null;
                    }
                }
            }
            GUILayout.EndHorizontal();
        }
        private static void DrawBoolField(SettingEntryBase setting)
        {
            var boolVal = (bool)setting.Get();
            var result  = GUILayout.Toggle(boolVal, boolVal ? "Enabled" : "Disabled", GUILayout.ExpandWidth(true));

            if (result != boolVal)
            {
                setting.Set(result);
            }
        }
        private static void DrawKeyboardShortcut(SettingEntryBase setting)
        {
#pragma warning disable 618 // Disable obsolete warning
            var value     = setting.Get();
            var isOldType = value is BepInEx.KeyboardShortcut;

            if (_currentKeyboardShortcutToSet == setting)
            {
                GUILayout.Label("Press any key combination", GUILayout.ExpandWidth(true));
                GUIUtility.keyboardControl = -1;

                foreach (var key in _keysToCheck)
                {
                    if (Input.GetKeyUp(key))
                    {
                        if (isOldType)
                        {
                            setting.Set(new BepInEx.KeyboardShortcut(key, _keysToCheck.Where(Input.GetKey).ToArray()));
                        }
                        else
                        {
                            setting.Set(new BepInEx.Configuration.KeyboardShortcut(key, _keysToCheck.Where(Input.GetKey).ToArray()));
                        }
                        _currentKeyboardShortcutToSet = null;
                        break;
                    }
                }

                if (GUILayout.Button("Cancel", GUILayout.ExpandWidth(false)))
                {
                    _currentKeyboardShortcutToSet = null;
                }
            }
            else
            {
                if (GUILayout.Button(value.ToString(), GUILayout.ExpandWidth(true)))
                {
                    _currentKeyboardShortcutToSet = setting;
                }

                if (GUILayout.Button("Clear", GUILayout.ExpandWidth(false)))
                {
                    if (isOldType)
                    {
                        setting.Set(new BepInEx.KeyboardShortcut());
                    }
                    else
                    {
                        setting.Set(BepInEx.Configuration.KeyboardShortcut.Empty);
                    }
                    _currentKeyboardShortcutToSet = null;
                }
            }
#pragma warning restore 618
        }
 private void DrawFieldBasedOnValueType(SettingEntryBase setting)
 {
     if (SettingDrawHandlers.TryGetValue(setting.SettingType, out var drawMethod))
     {
         drawMethod(setting);
     }
     else
     {
         DrawUnknownField(setting, _instance.RightColumnWidth);
     }
 }
        private static void DrawBoolField(SettingEntryBase setting)
        {
            GUI.backgroundColor = BepInExPlugin._widgetBackgroundColor.Value;
            var boolVal = (bool)setting.Get();
            var result  = GUILayout.Toggle(boolVal, boolVal ? "Enabled" : "Disabled", BepInExPlugin.toggleStyle, GUILayout.ExpandWidth(true));

            if (result != boolVal)
            {
                setting.Set(result);
            }
        }
        private void DrawSettingName(SettingEntryBase setting)
        {
            if (setting.HideSettingName)
            {
                return;
            }


            GUILayout.Label(new GUIContent(setting.DispName.TrimStart('!'), setting.Description), labelStyle,
                            GUILayout.Width(LeftColumnWidth), GUILayout.MaxWidth(LeftColumnWidth));
        }
        private static void DrawVector2(SettingEntryBase obj)
        {
            var setting = (Vector2)obj.Get();
            var copy    = setting;

            setting.x = DrawSingleVectorSlider(setting.x, "X");
            setting.y = DrawSingleVectorSlider(setting.y, "Y");
            if (setting != copy)
            {
                obj.Set(setting);
            }
        }
        private static void DrawQuaternion(SettingEntryBase obj)
        {
            var setting = (Quaternion)obj.Get();
            var copy    = setting;

            setting.x = DrawSingleVectorSlider(setting.x, "X");
            setting.y = DrawSingleVectorSlider(setting.y, "Y");
            setting.z = DrawSingleVectorSlider(setting.z, "Z");
            setting.w = DrawSingleVectorSlider(setting.w, "W");
            if (setting != copy)
            {
                obj.Set(setting);
            }
        }
        private static void DrawFlagsField(SettingEntryBase setting, IList enumValues, int maxWidth)
        {
            var currentValue = Convert.ToInt64(setting.Get());
            var allValues    = enumValues.Cast <Enum>().Select(x => new { name = x.ToString(), val = Convert.ToInt64(x) }).ToArray();

            // Vertically stack Horizontal groups of the options to deal with the options taking more width than is available in the window
            GUILayout.BeginVertical(GUILayout.MaxWidth(maxWidth));
            {
                for (var index = 0; index < allValues.Length;)
                {
                    GUILayout.BeginHorizontal();
                    {
                        var currentWidth = 0;
                        for (; index < allValues.Length; index++)
                        {
                            var value = allValues[index];

                            // Skip the 0 / none enum value, just uncheck everything to get 0
                            if (value.val != 0)
                            {
                                // Make sure this horizontal group doesn't extend over window width, if it does then start a new horiz group below
                                var textDimension = (int)GUI.skin.toggle.CalcSize(new GUIContent(value.name)).x;
                                currentWidth += textDimension;
                                if (currentWidth > maxWidth)
                                {
                                    break;
                                }

                                GUI.changed = false;


                                var newVal = GUILayout.Toggle((currentValue & value.val) == value.val, value.name, BepInExPlugin.toggleStyle,
                                                              GUILayout.ExpandWidth(false));
                                if (GUI.changed)
                                {
                                    var newValue = newVal ? currentValue | value.val : currentValue & ~value.val;
                                    setting.Set(Enum.ToObject(setting.SettingType, newValue));
                                }
                            }
                        }
                    }
                    GUILayout.EndHorizontal();
                }

                GUI.changed = false;
            }
            GUILayout.EndVertical();
            // Make sure the reset button is properly spaced
            GUILayout.FlexibleSpace();
        }
        private void DrawListField(SettingEntryBase setting)
        {
            var acceptableValues = setting.AcceptableValues;

            if (acceptableValues.Length == 0)
            {
                throw new ArgumentException("AcceptableValueListAttribute returned an empty list of acceptable values. You need to supply at least 1 option.");
            }

            if (!setting.SettingType.IsInstanceOfType(acceptableValues.FirstOrDefault(x => x != null)))
            {
                throw new ArgumentException("AcceptableValueListAttribute returned a list with items of type other than the settng type itself.");
            }

            DrawComboboxField(setting, acceptableValues, _instance.DefaultWindowRect.yMax);
        }
 private void DrawSingleSetting(SettingEntryBase setting)
 {
     GUILayout.BeginHorizontal();
     {
         try
         {
             DrawSettingName(setting);
             _fieldDrawer.DrawSettingValue(setting);
             DrawDefaultButton(setting);
         }
         catch (Exception ex)
         {
             Logger.Log(LogLevel.Error, $"Failed to draw setting {setting.DispName} - {ex}");
             GUILayout.Label("Failed to draw this field, check log for details.", labelStyle);
         }
     }
     GUILayout.EndHorizontal();
 }
        private static void DrawKeyboardShortcut(SettingEntryBase setting)
        {
            var value = setting.Get();

            if (value.GetType() == typeof(KeyCode))
            {
                value = new KeyboardShortcut((KeyCode)value);
            }

            if (_currentKeyboardShortcutToSet == setting)
            {
                GUILayout.Label("Press any key combination", BepInExPlugin.labelStyle, GUILayout.ExpandWidth(true));
                GUIUtility.keyboardControl = -1;

                foreach (var key in _keysToCheck)
                {
                    if (Input.GetKeyUp(key))
                    {
                        setting.Set(new BepInEx.Configuration.KeyboardShortcut(key, _keysToCheck.Where(Input.GetKey).ToArray()));
                        _currentKeyboardShortcutToSet = null;
                        break;
                    }
                }

                if (GUILayout.Button("Cancel", BepInExPlugin.buttonStyle, GUILayout.ExpandWidth(false)))
                {
                    _currentKeyboardShortcutToSet = null;
                }
            }
            else
            {
                if (GUILayout.Button(value.ToString(), GUILayout.ExpandWidth(true)))
                {
                    _currentKeyboardShortcutToSet = setting;
                }

                if (GUILayout.Button("Clear", BepInExPlugin.buttonStyle, GUILayout.ExpandWidth(false)))
                {
                    setting.Set(BepInEx.Configuration.KeyboardShortcut.Empty);
                    _currentKeyboardShortcutToSet = null;
                }
            }
        }
        private static void DrawRangeField(SettingEntryBase setting)
        {
            var value      = setting.Get();
            var converted  = (float)Convert.ToDouble(value, CultureInfo.InvariantCulture);
            var leftValue  = (float)Convert.ToDouble(setting.AcceptableValueRange.Key, CultureInfo.InvariantCulture);
            var rightValue = (float)Convert.ToDouble(setting.AcceptableValueRange.Value, CultureInfo.InvariantCulture);

            var result = GUILayout.HorizontalSlider(converted, leftValue, rightValue, BepInExPlugin.sliderStyle, BepInExPlugin.thumbStyle, GUILayout.ExpandWidth(true));

            if (Math.Abs(result - converted) > Mathf.Abs(rightValue - leftValue) / 1000)
            {
                var newValue = Convert.ChangeType(result, setting.SettingType, CultureInfo.InvariantCulture);
                setting.Set(newValue);
            }

            if (setting.ShowRangeAsPercent == true)
            {
                DrawCenteredLabel(
                    Mathf.Round(100 * Mathf.Abs(result - leftValue) / Mathf.Abs(rightValue - leftValue)) + "%",
                    GUILayout.Width(50));
            }
            else
            {
                var strVal    = value.ToString().AppendZeroIfFloat(setting.SettingType);
                var strResult = GUILayout.TextField(strVal, GUILayout.Width(50));
                if (strResult != strVal)
                {
                    try
                    {
                        var resultVal        = (float)Convert.ToDouble(strResult, CultureInfo.InvariantCulture);
                        var clampedResultVal = Mathf.Clamp(resultVal, leftValue, rightValue);
                        setting.Set(Convert.ChangeType(clampedResultVal, setting.SettingType, CultureInfo.InvariantCulture));
                    }
                    catch (FormatException)
                    {
                        // Ignore user typing in bad data
                    }
                }
            }
        }
 public void DrawSettingValue(SettingEntryBase setting)
 {
     if (setting.CustomDrawer != null)
     {
         setting.CustomDrawer(setting is ConfigSettingEntry newSetting ? newSetting.Entry : null);
     }
     else if (setting.ShowRangeAsPercent != null && setting.AcceptableValueRange.Key != null)
     {
         DrawRangeField(setting);
     }
     else if (setting.AcceptableValues != null)
     {
         DrawListField(setting);
     }
     else if (setting.SettingType.IsEnum)
     {
         DrawComboboxField(setting, Enum.GetValues(setting.SettingType), _instance.SettingWindowRect.yMax);
     }
     else
     {
         DrawFieldBasedOnValueType(setting);
     }
 }
        private static void DrawComboboxField(SettingEntryBase setting, IList list, float windowYmax)
        {
            var buttonText = ObjectToGuiContent(setting.Get());
            var dispRect   = GUILayoutUtility.GetRect(buttonText, GUI.skin.button, GUILayout.ExpandWidth(true));

            if (!_comboBoxCache.TryGetValue(setting, out var box))
            {
                box = new ComboBox(dispRect, buttonText, list.Cast <object>().Select(ObjectToGuiContent).ToArray(), BepInExPlugin.boxStyle, windowYmax);
                _comboBoxCache[setting] = box;
            }
            else
            {
                box.Rect          = dispRect;
                box.ButtonContent = buttonText;
            }

            box.Show(id =>
            {
                if (id >= 0 && id < list.Count)
                {
                    setting.Set(list[id]);
                }
            });
        }