Esempio n. 1
0
        /// <summary>
        /// Import settings for Mod.
        /// </summary>
        /// <param name="mod">Mod to load settings for.</param>
        public ModSettings(Mod mod)
        {
            if (!mod.HasSettings)
            {
                throw new ArgumentException(string.Format("{0} has no settings.", mod.Title), "mod");
            }

            this.mod = mod;
            ModSettingsReader.GetSettings(mod, out userSettings, out config);
        }
        private TextLabel AddKeyName(string name)
        {
            TextLabel textLabel = new TextLabel();

            textLabel.Text                = ModSettingsReader.FormattedName(name);
            textLabel.ShadowColor         = Color.clear;
            textLabel.TextScale           = textScale;
            textLabel.Position            = new Vector2(x, y);
            textLabel.HorizontalAlignment = HorizontalAlignment.None;
            currentPanel.Components.Add(textLabel);
            return(textLabel);
        }
Esempio n. 3
0
        /// <summary>
        /// Get color from user settings or, as fallback, from default settings.
        /// </summary>
        /// <param name="section">Name of section inside .ini</param>
        /// <param name="name">Name of key inside .ini</param>
        public Color GetColor(string section, string name)
        {
            string colorString = GetValue(section, name);
            int    hexColor    = 0;

            if (int.TryParse(colorString, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out hexColor))
            {
                return(ModSettingsReader.ColorFromString(colorString));
            }

            Debug.LogError(colorString + " from " + Mod.FileName + ".ini is not a valid color. Using default color.");
            return(ModSettingsReader.ColorFromString(defaultSettings[section][name]));
        }
Esempio n. 4
0
 /// <summary>
 /// Set default settings on confirmation.
 /// </summary>
 private void ConfirmReset_OnButtonClick(DaggerfallMessageBox sender, DaggerfallMessageBox.MessageBoxButtons messageBoxButton)
 {
     if (messageBoxButton == DaggerfallMessageBox.MessageBoxButtons.Yes)
     {
         ModSettingsReader.ResetSettings(mod, ref data, defaultSettings);
         CloseWindow();
         RestartSettingsWindow();
     }
     else
     {
         CloseWindow();
     }
 }
        /// <summary>
        /// Save settings inside IniData.
        /// </summary>
        /// <param name="writeToDisk">Write settings to ini file on disk.</param>
        private void SaveSettings(bool writeToDisk = true)
        {
            // Set new values
            int checkBox = 0, textBox = 0, tuple = 0, slider = 0, colorPicker = 0;

            foreach (var section in config.VisibleSections)
            {
                foreach (var key in section.keys)
                {
                    switch (key.type)
                    {
                    case ModSettingsKey.KeyType.Toggle:
                        data[section.name][key.name] = modCheckboxes[checkBox].IsChecked.ToString();
                        checkBox++;
                        break;

                    case ModSettingsKey.KeyType.MultipleChoice:
                    case ModSettingsKey.KeyType.Slider:
                    case ModSettingsKey.KeyType.FloatSlider:
                        data[section.name][key.name] = modSliders[slider].GetValue().ToString();
                        slider++;
                        break;

                    case ModSettingsKey.KeyType.Tuple:
                    case ModSettingsKey.KeyType.FloatTuple:
                        string value = modTuples[tuple].First.ResultText + ModSettingsReader.tupleDelimiterChar + modTuples[tuple].Second.ResultText;
                        data[section.name][key.name] = value;
                        tuple++;
                        break;

                    case ModSettingsKey.KeyType.Text:
                        data[section.name][key.name] = modTextBoxes[textBox].ResultText;
                        textBox++;
                        break;

                    case ModSettingsKey.KeyType.Color:
                        string hexColor = ColorUtility.ToHtmlStringRGBA(modColorPickers[colorPicker].BackgroundColor);
                        data[section.name][key.name] = hexColor;
                        colorPicker++;
                        break;
                    }
                }
            }

            // Save to file
            if (writeToDisk)
            {
                ModSettingsReader.SaveSettings(mod, data);
            }
        }
Esempio n. 6
0
        private void Keys_DrawHeaderCallback(Rect rect)
        {
            SerializedProperty _sectionName = _sections.GetArrayElementAtIndex(currentSection).FindPropertyRelative("name");

            if (!sectionExpanded.ContainsKey(currentSection))
            {
                sectionExpanded.Add(currentSection, false);
            }
            var style = new GUIStyle(EditorStyles.foldout);

            if (_sectionName.stringValue == ModSettingsReader.internalSection)
            {
                style.normal.textColor = Color.red;
            }
            sectionExpanded[currentSection] = EditorGUI.Foldout(LineRect(rect), sectionExpanded[currentSection],
                                                                ModSettingsReader.FormattedName(_sectionName.stringValue), style);
        }
        protected override void Setup()
        {
            // Get settings
            ModSettingsReader.GetSettings(mod, out data, out config);
            presets = ModSettingsReader.GetPresets(mod);

            // Setup base panel
            ParentPanel.BackgroundColor          = Color.clear;
            modSettingsPanel.BackgroundColor     = panelBackgroundColor;
            modSettingsPanel.Outline.Enabled     = true;
            modSettingsPanel.HorizontalAlignment = HorizontalAlignment.Center;
            modSettingsPanel.Position            = new Vector2(0, 8);
            modSettingsPanel.Size = new Vector2(320, 175);
            NativePanel.Components.Add(modSettingsPanel);

            // Initialize window
            Init();
        }
        Color sectionTitleColor    = new Color(0.16f, 0.26f, 1, 1);     // light blue

        #endregion

        #region Setup

        /// <summary>
        /// Setup the panel.
        /// </summary>
        protected override void Setup()
        {
            // Set path
            path = Path.Combine(Mod.DirPath, Mod.FileName + ".ini");

            // Default settings
            defaultSettings = ModSettingsReader.GetDefaultSettings(Mod);

            // Presets
            presets = ModSettingsReader.GetPresets(Mod);

            // Add panel
            ParentPanel.BackgroundColor          = Color.clear;
            modSettingsPanel.BackgroundColor     = panelBackgroundColor;
            modSettingsPanel.Outline.Enabled     = true;
            modSettingsPanel.HorizontalAlignment = HorizontalAlignment.Center;
            modSettingsPanel.Position            = new Vector2(0, 8);
            modSettingsPanel.Size = new Vector2(320, 175);
            NativePanel.Components.Add(modSettingsPanel);
            InitPanel();
        }
Esempio n. 9
0
        private void AddColorPicker(string hexColor, ModSettingsKey key = null)
        {
            Button colorPicker = new Button()
            {
                Position = new Vector2(x + 95, y),
                AutoSize = AutoSizeModes.None,
                Size     = new Vector2(40, 6),
            };

            colorPicker.Outline.Enabled = true;

            if (!ModSettingsReader.IsHexColor(hexColor))
            {
                hexColor = key != null ? key.color.HexColor : "FFFFFFFF";
            }
            colorPicker.BackgroundColor = ModSettingsReader.ColorFromString(hexColor);

            colorPicker.OnMouseClick += ColorPicker_OnMouseClick;
            modColorPickers.Add(colorPicker);
            currentPanel.Components.Add(colorPicker);
        }
        private void AddSectionTitle(string title)
        {
            Panel background = new Panel();

            background.Position          = new Vector2(x, y - 0.5f);
            background.Size              = new Vector2(140, 6.5f);
            background.BackgroundColor   = backgroundTitleColor;
            background.Outline.Enabled   = true;
            background.Outline.Sides     = Sides.Bottom;
            background.Outline.Color     = saveButtonColor;
            background.Outline.Thickness = 1;
            currentPanel.Components.Add(background);

            TextLabel textLabel = new TextLabel(DaggerfallUI.Instance.Font5);

            textLabel.Text                = ModSettingsReader.FormattedName(title);
            textLabel.TextColor           = sectionTitleColor;
            textLabel.ShadowColor         = sectionTitleShadow;
            textLabel.TextScale           = 0.9f;
            textLabel.Position            = new Vector2(0, 0.5f);
            textLabel.HorizontalAlignment = HorizontalAlignment.Center;
            background.Components.Add(textLabel);
        }
Esempio n. 11
0
        /// <summary>
        /// Import settings for Mod.
        /// </summary>
        /// <param name="mod">Mod to load settings for.</param>
        /// <returns></returns>
        public ModSettings(Mod mod)
        {
            Mod  = mod;
            path = Path.Combine(mod.DirPath, Mod.FileName + ".ini");

            // Read default settings
            defaultSettings = ModSettingsReader.GetDefaultSettings(Mod);

            // Read user settings
            if (File.Exists(path))
            {
                userSettings = parser.ReadFile(path);
                ModSettingsReader.UpdateSettings(ref userSettings, defaultSettings, Mod);
            }
            else
            {
                // Create settings file with default values
                userSettings = defaultSettings;
                parser.WriteFile(path, defaultSettings);
                Debug.Log(Mod.Title + ": failed to read " + path + "." + Mod.FileName + ": A new " + Mod.FileName
                          + ".ini has been recreated with default settings");
            }
        }
Esempio n. 12
0
        /// <summary>
        /// Import settings for Mod.
        /// </summary>
        /// <param name="mod">Mod to load settings for.</param>
        public ModSettings(Mod mod)
        {
            Mod = mod;

            ModSettingsReader.GetSettings(mod, out userSettings, out defaultSettings);
        }
 public void ImportFromIni()
 {
     ModSettingsReader.ParseIniToConfig((new FileIniDataParser()).ReadFile(IniPath), this);
 }
Esempio n. 14
0
        /// <summary>
        /// Save settings inside IniData.
        /// </summary>
        /// <param name="writeToDisk">Write settings to ini file on disk.</param>
        private void SaveSettings(bool writeToDisk = true)
        {
            // Set new values
            int checkBox = 0, textBox = 0, tuple = 0, slider = 0, colorPicker = 0;

            foreach (SectionData section in data.Sections.Where(x => x.SectionName != ModSettingsReader.internalSection))
            {
                foreach (KeyData key in section.Keys)
                {
                    ModSettingsKey configKey;
                    if (config && config.Key(section.SectionName, key.KeyName, out configKey))
                    {
                        switch (configKey.type)
                        {
                        case ModSettingsKey.KeyType.Toggle:
                            data[section.SectionName][key.KeyName] = modCheckboxes[checkBox].IsChecked.ToString();
                            checkBox++;
                            break;

                        case ModSettingsKey.KeyType.MultipleChoice:
                        case ModSettingsKey.KeyType.Slider:
                        case ModSettingsKey.KeyType.FloatSlider:
                            data[section.SectionName][key.KeyName] = modSliders[slider].GetValue().ToString();
                            slider++;
                            break;

                        case ModSettingsKey.KeyType.Tuple:
                        case ModSettingsKey.KeyType.FloatTuple:
                            string value = modTuples[tuple].First.ResultText + ModSettingsReader.tupleDelimiterChar + modTuples[tuple].Second.ResultText;
                            data[section.SectionName][key.KeyName] = value;
                            tuple++;
                            break;

                        case ModSettingsKey.KeyType.Text:
                            data[section.SectionName][key.KeyName] = modTextBoxes[textBox].ResultText;
                            textBox++;
                            break;

                        case ModSettingsKey.KeyType.Color:
                            string hexColor = ColorUtility.ToHtmlStringRGBA(modColorPickers[colorPicker].BackgroundColor);
                            data[section.SectionName][key.KeyName] = hexColor;
                            colorPicker++;
                            break;
                        }
                    }
                    else if (key.Value == "True" || key.Value == "False")
                    {
                        data[section.SectionName][key.KeyName] = modCheckboxes[checkBox].IsChecked.ToString();
                        checkBox++;
                    }
                    else if (key.Value.Contains(ModSettingsReader.tupleDelimiterChar))
                    {
                        string value = modTuples[tuple].First.ResultText + ModSettingsReader.tupleDelimiterChar + modTuples[tuple].Second.ResultText;
                        data[section.SectionName][key.KeyName] = value;
                        tuple++;
                    }
                    else
                    {
                        data[section.SectionName][key.KeyName] = modTextBoxes[textBox].ResultText;
                        textBox++;
                    }
                }
            }

            // Save to file
            if (writeToDisk)
            {
                ModSettingsReader.SaveSettings(mod, data);
            }
        }
Esempio n. 15
0
        /// <summary>
        /// Load settings from IniData.
        /// </summary>
        private void LoadSettings()
        {
            // Read settings
            foreach (SectionData section in data.Sections.Where(x => x.SectionName != ModSettingsReader.internalSection))
            {
                // Section title
                AddSectionTitle(section.SectionName);
                MovePosition(spacing);
                List <string> comments = section.Comments;
                int           comment  = 0;

                foreach (KeyData key in section.Keys)
                {
                    // Setting label
                    TextLabel settingName = AddKeyName(key.KeyName);

                    // Setting field
                    ModSettingsKey configKey;
                    if (config && config.Key(section.SectionName, key.KeyName, out configKey))
                    {
                        settingName.ToolTip     = defaultToolTip;
                        settingName.ToolTipText = configKey.description;

                        // Use config file
                        switch (configKey.type)
                        {
                        case ModSettingsKey.KeyType.Toggle:
                            bool toggle;
                            AddCheckBox((bool.TryParse(key.Value, out toggle) && toggle) || configKey.toggle.value);
                            break;

                        case ModSettingsKey.KeyType.MultipleChoice:
                            int selected;
                            if (!int.TryParse(key.Value, out selected))
                            {
                                selected = configKey.multipleChoice.selected;
                            }
                            var multipleChoice = GetSlider();
                            multipleChoice.SetIndicator(configKey.multipleChoice.choices, selected);
                            SetSliderIndicator(multipleChoice);
                            break;

                        case ModSettingsKey.KeyType.Slider:
                            var sliderKey = configKey.slider;
                            int startValue;
                            if (!int.TryParse(key.Value, out startValue))
                            {
                                startValue = configKey.slider.value;
                            }
                            var slider = GetSlider();
                            slider.SetIndicator(sliderKey.min, sliderKey.max, startValue);
                            SetSliderIndicator(slider);
                            break;

                        case ModSettingsKey.KeyType.FloatSlider:
                            var   floatSliderKey = configKey.floatSlider;
                            float floatStartValue;
                            if (!float.TryParse(key.Value, out floatStartValue))
                            {
                                floatStartValue = configKey.floatSlider.value;
                            }
                            var floatSlider = GetSlider();
                            floatSlider.SetIndicator(floatSliderKey.min, floatSliderKey.max, floatStartValue);
                            SetSliderIndicator(floatSlider);
                            break;

                        case ModSettingsKey.KeyType.Tuple:
                            var tuple = AddTuple(key.Value);
                            tuple.First.Numeric = tuple.Second.Numeric = true;
                            break;

                        case ModSettingsKey.KeyType.FloatTuple:
                            AddTuple(key.Value);     // TextBox.Numeric doesn't allow dot
                            break;

                        case ModSettingsKey.KeyType.Text:
                            TextBox textBox = GetTextbox(95, 40, key.Value);
                            modTextBoxes.Add(textBox);
                            break;

                        case ModSettingsKey.KeyType.Color:
                            AddColorPicker(key.Value, configKey);
                            break;
                        }
                    }
                    else
                    {
                        // Legacy support
                        if (comment < comments.Count)
                        {
                            settingName.ToolTip     = defaultToolTip;
                            settingName.ToolTipText = comments[comment];
                            comment++;
                        }

                        if (key.Value == "True")
                        {
                            AddCheckBox(true);
                        }
                        else if (key.Value == "False")
                        {
                            AddCheckBox(false);
                        }
                        else if (key.Value.Contains(ModSettingsReader.tupleDelimiterChar))
                        {
                            AddTuple(key.Value);
                        }
                        else if (ModSettingsReader.IsHexColor(key.Value))
                        {
                            AddColorPicker(key.Value);
                        }
                        else
                        {
                            TextBox textBox = GetTextbox(95, 40, key.Value);
                            modTextBoxes.Add(textBox);
                        }
                    }

                    MovePosition(spacing);
                }
            }
        }
 public void ExportToIni()
 {
     File.WriteAllText(IniPath, ModSettingsReader.ParseConfigToIni(this).ToString());
 }
Esempio n. 17
0
        /// <summary>
        /// Load settings from IniData.
        /// This will be read from the ini file on disk the first time.
        /// </summary>
        private void LoadSettings()
        {
            // Read file
            if (data == null)
            {
                data = parser.ReadFile(path);
                ModSettingsReader.UpdateSettings(ref data, defaultSettings, Mod);
            }

            // Read settings
            int numberOfElements = 0;

            foreach (SectionData section in data.Sections.Where(x => x.SectionName != ModSettingsReader.internalSection))
            {
                // Section label
                y += spacing;
                TextLabel textLabel = new TextLabel();
                textLabel.Text                = section.SectionName;
                textLabel.TextColor           = sectionTitleColor;
                textLabel.Position            = new Vector2(x, y);
                textLabel.HorizontalAlignment = HorizontalAlignment.None;
                currentPanel.Components.Add(textLabel);

                UpdateItemsCount(ref numberOfElements);
                List <string> comments = section.Comments;
                int           comment  = 0;

                foreach (KeyData key in section.Keys)
                {
                    y += spacing;

                    // Setting label
                    TextLabel settingName = new TextLabel();
                    settingName.Text                = key.KeyName;
                    settingName.Position            = new Vector2(x, y);
                    settingName.HorizontalAlignment = HorizontalAlignment.None;
                    if (comment < comments.Count)
                    {
                        settingName.ToolTip     = defaultToolTip;
                        settingName.ToolTipText = comments[comment];
                        comment++;
                    }
                    currentPanel.Components.Add(settingName);

                    // Setting field
                    if (key.Value == "True")
                    {
                        AddCheckBox(true);
                    }
                    else if (key.Value == "False")
                    {
                        AddCheckBox(false);
                    }
                    else if (key.Value.Contains(ModSettingsReader.tupleDelimiterChar)) // Tuple
                    {
                        int index  = key.Value.IndexOf(ModSettingsReader.tupleDelimiterChar);
                        var first  = GetTextbox(95, 19.6f, key.Value.Substring(0, index));
                        var second = GetTextbox(116, 19.6f, key.Value.Substring(index + ModSettingsReader.tupleDelimiterChar.Length));
                        modTuples.Add(new Tuple <TextBox, TextBox>(first, second));
                    }
                    else
                    {
                        TextBox textBox = GetTextbox(95, 40, key.Value);
                        modTextBoxes.Add(textBox);

                        // Color
                        if (textBox.DefaultText.Length == 8)
                        {
                            // Check if is a hex number or just a string with lenght eight
                            int hexColor;
                            if (int.TryParse(textBox.DefaultText, System.Globalization.NumberStyles.HexNumber,
                                             System.Globalization.CultureInfo.InvariantCulture, out hexColor))
                            {
                                // Use box background as a preview of the color
                                Color32 color = ModSettingsReader.ColorFromString(textBox.DefaultText);
                                textBox.BackgroundColor = color;
                                textBox.ToolTip         = defaultToolTip;
                                textBox.ToolTipText     = color.ToString();
                            }
                        }
                    }

                    UpdateItemsCount(ref numberOfElements);
                }
            }
        }
 private void PresetPicker_OnCreatePreset(Preset preset)
 {
     SaveSettings(false);
     ModSettingsReader.CreatePreset(mod, data, preset);
     presets = ModSettingsReader.GetPresets(mod);
 }
Esempio n. 19
0
        private void Keys_DrawElementCallback(Rect rect, int index, bool isActive, bool isFocused)
        {
            int line = 0;

            SerializedProperty _keys    = _sections.GetArrayElementAtIndex(currentSection).FindPropertyRelative("keys");
            SerializedProperty _key     = _keys.GetArrayElementAtIndex(index);
            SerializedProperty _keyName = _key.FindPropertyRelative("name");

            if (!sectionExpanded[currentSection])
            {
                EditorGUI.LabelField(LineRect(rect), ModSettingsReader.FormattedName(_keyName.stringValue));
                SetKeySize(currentSection, index, lineHeight);
                return;
            }

            SerializedProperty _type = _key.FindPropertyRelative("type");

            using (new EditorGUI.DisabledScope(isPreset))
            {
                EditorGUI.PropertyField(LineRect(rect, line++), _keyName, GUIContent.none);
                EditorGUI.PropertyField(LineRect(rect, line++), _key.FindPropertyRelative("description"));
                EditorGUI.PropertyField(LineRect(rect, line++), _type, new GUIContent("UI Control"));
            }

            int lines = 4;

            switch ((ModSettingsKey.KeyType)_type.enumValueIndex)
            {
            case ModSettingsKey.KeyType.Toggle:
                SerializedProperty _value = _key.FindPropertyRelative("toggle").FindPropertyRelative("value");
                EditorGUI.PropertyField(LineRect(rect, line++), _value, true);
                break;

            case ModSettingsKey.KeyType.MultipleChoice:
                SerializedProperty _multipleChoice = _key.FindPropertyRelative("multipleChoice");
                SerializedProperty _selected       = _multipleChoice.FindPropertyRelative("selected");
                SerializedProperty _choices        = _multipleChoice.FindPropertyRelative("choices");
                var      multipleChoice            = Target.sections[currentSection].keys[index].multipleChoice;
                string[] choices = multipleChoice.choices;
                _selected.intValue = EditorGUI.Popup(LineRect(rect, line++), _selected.intValue, choices);
                using (new EditorGUI.DisabledScope(isPreset))
                {
                    if (DropDownButton(rect, line))
                    {
                        var menu = new GenericMenu();
                        menu.AddItem(new GUIContent("Copy choices"), false, CopyChoices, new List <string>(choices));
                        if (cachedChoices != null)
                        {
                            menu.AddItem(new GUIContent("Paste choices"), false, PasteChoices, multipleChoice);
                        }
                        menu.ShowAsContext();
                    }
                    EditorGUI.PropertyField(LineRect(rect, line++), _choices, true);
                }
                lines += _choices.isExpanded ? 2 + choices.Length : 1;
                break;

            case ModSettingsKey.KeyType.Slider:
                SerializedProperty _slider    = _key.FindPropertyRelative("slider");
                SerializedProperty _sliderMin = _slider.FindPropertyRelative("min");
                SerializedProperty _sliderMax = _slider.FindPropertyRelative("max");
                if (_sliderMin.intValue == 0 && _sliderMax.intValue == 0)
                {
                    _sliderMax.intValue = 100;
                }
                EditorGUI.IntSlider(LineRect(rect, line++),
                                    _slider.FindPropertyRelative("value"), _sliderMin.intValue, _sliderMax.intValue);
                GUILayout.BeginHorizontal();
                using (new EditorGUI.DisabledScope(isPreset))
                {
                    EditorGUI.PropertyField(HalfLineRect(rect, line), _sliderMin);
                    EditorGUI.PropertyField(HalfLineRect(rect, line++, true), _sliderMax);
                }
                GUILayout.EndHorizontal();
                lines += 1;
                break;

            case ModSettingsKey.KeyType.FloatSlider:
                SerializedProperty _floatSlider      = _key.FindPropertyRelative("floatSlider");
                SerializedProperty _floatSliderValue = _floatSlider.FindPropertyRelative("value");
                SerializedProperty _floatSliderMin   = _floatSlider.FindPropertyRelative("min");
                SerializedProperty _floatSliderMax   = _floatSlider.FindPropertyRelative("max");
                if (_floatSliderMin.floatValue == 0 && _floatSliderMax.floatValue == 0)
                {
                    _floatSliderMax.floatValue = 1;
                }
                EditorGUI.Slider(LineRect(rect, line++), _floatSliderValue, _floatSliderMin.floatValue, _floatSliderMax.floatValue);
                GUILayout.BeginHorizontal();
                using (new EditorGUI.DisabledScope(isPreset))
                {
                    EditorGUI.PropertyField(HalfLineRect(rect, line), _floatSliderMin);
                    EditorGUI.PropertyField(HalfLineRect(rect, line++, true), _floatSliderMax);
                }
                GUILayout.EndHorizontal();
                lines += 1;
                break;

            case ModSettingsKey.KeyType.Tuple:
                SerializedProperty _tuple = _key.FindPropertyRelative("tuple");
                GUILayout.BeginHorizontal();
                EditorGUI.PropertyField(HalfLineRect(rect, line), _tuple.FindPropertyRelative("first"), GUIContent.none);
                EditorGUI.PropertyField(HalfLineRect(rect, line++, true), _tuple.FindPropertyRelative("second"), GUIContent.none);
                GUILayout.EndHorizontal();
                break;

            case ModSettingsKey.KeyType.FloatTuple:
                SerializedProperty _floatTuple = _key.FindPropertyRelative("floatTuple");
                GUILayout.BeginHorizontal();
                EditorGUI.PropertyField(HalfLineRect(rect, line), _floatTuple.FindPropertyRelative("first"), GUIContent.none);
                EditorGUI.PropertyField(HalfLineRect(rect, line++, true), _floatTuple.FindPropertyRelative("second"), GUIContent.none);
                GUILayout.EndHorizontal();
                break;

            case ModSettingsKey.KeyType.Text:
                EditorGUI.PropertyField(new Rect(rect.x, rect.y + 3 * lineHeight, rect.width, EditorGUIUtility.singleLineHeight * 3),
                                        _key.FindPropertyRelative("text").FindPropertyRelative("text"));
                lines += 2;
                break;

            case ModSettingsKey.KeyType.Color:
                EditorGUI.PropertyField(LineRect(rect, line++), _key.FindPropertyRelative("color").FindPropertyRelative("color"));
                break;
            }

            SetKeySize(currentSection, index, (lines + 1) * lineHeight);
        }
        /// <summary>
        /// Load settings from IniData.
        /// This will be read from the ini file on disk the first time.
        /// </summary>
        private void LoadSettings()
        {
            // Read file
            if (data == null)
            {
                data = parser.ReadFile(path);
                ModSettingsReader.UpdateSettings(ref data, defaultSettings, Mod);
                config = ModSettingsReader.GetConfig(Mod);
            }

            // Read settings
            foreach (SectionData section in data.Sections.Where(x => x.SectionName != ModSettingsReader.internalSection))
            {
                // Section label
                TextLabel textLabel = new TextLabel();
                textLabel.Text                = section.SectionName;
                textLabel.TextColor           = sectionTitleColor;
                textLabel.Position            = new Vector2(x, y);
                textLabel.HorizontalAlignment = HorizontalAlignment.None;
                currentPanel.Components.Add(textLabel);
                MovePosition(spacing + 4);
                List <string> comments = section.Comments;
                int           comment  = 0;

                foreach (KeyData key in section.Keys)
                {
                    // Setting label
                    TextLabel settingName = new TextLabel();
                    settingName.Text                = key.KeyName;
                    settingName.Position            = new Vector2(x, y);
                    settingName.HorizontalAlignment = HorizontalAlignment.None;
                    if (comment < comments.Count)
                    {
                        settingName.ToolTip     = defaultToolTip;
                        settingName.ToolTipText = comments[comment];
                        comment++;
                    }
                    currentPanel.Components.Add(settingName);

                    // Setting field
                    ModSettingsKey configKey;
                    if (config && config.Key(section.SectionName, key.KeyName, out configKey))
                    {
                        settingName.ToolTipText = configKey.description;

                        // Use config file
                        switch (configKey.type)
                        {
                        case ModSettingsKey.KeyType.Toggle:
                            AddCheckBox(key.Value == "True");
                            break;

                        case ModSettingsKey.KeyType.Slider:
                            var slider = configKey.slider;
                            int startValue;
                            if (!int.TryParse(key.Value, out startValue))
                            {
                                startValue = 0;
                            }
                            AddSlider(slider.min, slider.max, startValue, key.KeyName);
                            break;

                        case ModSettingsKey.KeyType.FloatSlider:
                            var   floatSlider = configKey.floatSlider;
                            float floatStartValue;
                            if (!float.TryParse(key.Value, out floatStartValue))
                            {
                                floatStartValue = 0;
                            }
                            AddSlider(floatSlider.min, floatSlider.max, floatStartValue, key.KeyName);
                            break;

                        case ModSettingsKey.KeyType.Tuple:
                        case ModSettingsKey.KeyType.FloatTuple:
                            int index  = key.Value.IndexOf(ModSettingsReader.tupleDelimiterChar);
                            var first  = GetTextbox(95, 19.6f, key.Value.Substring(0, index));
                            var second = GetTextbox(116, 19.6f, key.Value.Substring(index + ModSettingsReader.tupleDelimiterChar.Length));
                            modTuples.Add(new Tuple <TextBox, TextBox>(first, second));
                            break;

                        case ModSettingsKey.KeyType.Text:
                        case ModSettingsKey.KeyType.MultipleChoice:     //TODO
                            TextBox textBox = GetTextbox(95, 40, key.Value);
                            modTextBoxes.Add(textBox);
                            break;

                        case ModSettingsKey.KeyType.Color:
                            TextBox colorBox = GetTextbox(95, 40, key.Value);
                            modTextBoxes.Add(colorBox);
                            int hexColor;
                            if (colorBox.DefaultText.Length != 8 || !int.TryParse(colorBox.DefaultText, System.Globalization.NumberStyles.HexNumber,
                                                                                  System.Globalization.CultureInfo.InvariantCulture, out hexColor))
                            {
                                colorBox.DefaultText = "FFFFFFFF";
                            }
                            // Use box background as a preview of the color
                            Color32 color = ModSettingsReader.ColorFromString(colorBox.DefaultText);
                            colorBox.BackgroundColor = color;
                            colorBox.ToolTip         = defaultToolTip;
                            colorBox.ToolTipText     = color.ToString();
                            break;
                        }
                    }
                    else
                    {
                        // Legacy support
                        if (key.Value == "True")
                        {
                            AddCheckBox(true);
                        }
                        else if (key.Value == "False")
                        {
                            AddCheckBox(false);
                        }
                        else if (key.Value.Contains(ModSettingsReader.tupleDelimiterChar)) // Tuple
                        {
                            int index  = key.Value.IndexOf(ModSettingsReader.tupleDelimiterChar);
                            var first  = GetTextbox(95, 19.6f, key.Value.Substring(0, index));
                            var second = GetTextbox(116, 19.6f, key.Value.Substring(index + ModSettingsReader.tupleDelimiterChar.Length));
                            modTuples.Add(new Tuple <TextBox, TextBox>(first, second));
                        }
                        else
                        {
                            TextBox textBox = GetTextbox(95, 40, key.Value);
                            modTextBoxes.Add(textBox);

                            // Color
                            if (textBox.DefaultText.Length == 8)
                            {
                                // Check if is a hex number or just a string with lenght eight
                                int hexColor;
                                if (int.TryParse(textBox.DefaultText, System.Globalization.NumberStyles.HexNumber,
                                                 System.Globalization.CultureInfo.InvariantCulture, out hexColor))
                                {
                                    // Use box background as a preview of the color
                                    Color32 color = ModSettingsReader.ColorFromString(textBox.DefaultText);
                                    textBox.BackgroundColor = color;
                                    textBox.ToolTip         = defaultToolTip;
                                    textBox.ToolTipText     = color.ToString();
                                }
                            }
                        }
                    }

                    MovePosition(spacing);
                }
            }
        }