private void DrawMainList()
        {
            // The bold table headings
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Key", EditorStyles.boldLabel);
            GUILayout.Label("Value", EditorStyles.boldLabel);
            GUILayout.Label("Type", EditorStyles.boldLabel, GUILayout.Width(37));
            GUILayout.Label("Del", EditorStyles.boldLabel, GUILayout.Width(25));
            EditorGUILayout.EndHorizontal();

            // Create a GUIStyle that can be manipulated for the various text fields
            GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField);

            // Could be dealing with either the full list or search results, so get the right list
            List <PlayerPrefPair> activePlayerPrefs = deserializedPlayerPrefs;

            if (!string.IsNullOrEmpty(searchFilter))
            {
                activePlayerPrefs = filteredPlayerPrefs;
            }

            // Cache the entry count
            int entryCount = activePlayerPrefs.Count;

            // Record the last scroll position so we can calculate if the user has scrolled this frame
            lastScrollPosition = scrollPosition;

            // Start the scrollable area
            scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
            // Ensure the scroll doesn't go below zero
            if (scrollPosition.y < 0)
            {
                scrollPosition.y = 0;
            }

            // The following code has been optimised so that rather than attempting to draw UI for every single PlayerPref
            // it instead only draws the UI for those currently visible in the scroll view and pads above and below those
            // results to maintain the right size using GUILayout.Space(). This enables us to work with thousands of
            // PlayerPrefs without slowing the interface to a halt.

            // Fixed height of one of the rows in the table
            float rowHeight = 18;

            // Determine how many rows are visible on screen. For simplicity, use Screen.height (the overhead is negligible)
            int visibleCount = Mathf.CeilToInt(Screen.height / rowHeight);

            // Determine the index of the first player pref that should be drawn as visible in the scrollable area
            int firstShownIndex = Mathf.FloorToInt(scrollPosition.y / rowHeight);

            // Determine the bottom limit of the visible player prefs (last shown index + 1)
            int shownIndexLimit = firstShownIndex + visibleCount;

            // If the actual number of player prefs is smaller than the caculated limit, reduce the limit to match
            if (entryCount < shownIndexLimit)
            {
                shownIndexLimit = entryCount;
            }

            // If the number of displayed player prefs is smaller than the number we can display (like we're at the end
            // of the list) then move the starting index back to adjust
            if (shownIndexLimit - firstShownIndex < visibleCount)
            {
                firstShownIndex -= visibleCount - (shownIndexLimit - firstShownIndex);
            }

            // Can't have a negative index of a first shown player pref, so clamp to 0
            if (firstShownIndex < 0)
            {
                firstShownIndex = 0;
            }

            // Pad above the on screen results so that we're not wasting draw calls on invisible UI and the drawn player
            // prefs end up in the same place in the list
            GUILayout.Space(firstShownIndex * rowHeight);

            // For each of the on screen results
            for (int i = firstShownIndex; i < shownIndexLimit; i++)
            {
                // Detect if it's an encrypted player pref (these have key prefixes)
                bool isEncryptedPair = PlayerPrefsUtility.IsEncryptedKey(activePlayerPrefs[i].Key);

                // Colour code encrypted player prefs blue
                if (isEncryptedPair)
                {
                    if (UsingProSkin)
                    {
                        textFieldStyle.normal.textColor  = new Color(0.5f, 0.5f, 1);
                        textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1);
                    }
                    else
                    {
                        textFieldStyle.normal.textColor  = new Color(0, 0, 1);
                        textFieldStyle.focused.textColor = new Color(0, 0, 1);
                    }
                }
                else
                {
                    // Normal player prefs are just black
                    textFieldStyle.normal.textColor  = GUI.skin.textField.normal.textColor;
                    textFieldStyle.focused.textColor = GUI.skin.textField.focused.textColor;
                }

                // The full key is the key that's actually stored in player prefs
                string fullKey = activePlayerPrefs[i].Key;

                // Display key is used so in the case of encrypted keys, we display the decrypted version instead (in
                // auto-decrypt mode).
                string displayKey = fullKey;

                // Used for accessing the type information stored against the player pref
                object deserializedValue = activePlayerPrefs[i].Value;

                // Track whether the auto decrypt failed, so we can instead fallback to encrypted values and mark it red
                bool failedAutoDecrypt = false;

                // If this is an encrypted play pref and we're attempting to decrypt them, try to decrypt it!
                if (isEncryptedPair && automaticDecryption)
                {
                    // This may throw exceptions (e.g. if private key changes), so wrap in a try-catch
                    try
                    {
                        deserializedValue = PlayerPrefsUtility.GetEncryptedValue(fullKey, (string)deserializedValue);
                        displayKey        = PlayerPrefsUtility.DecryptKey(fullKey);
                    }
                    catch
                    {
                        // Change the colour to red to highlight the decrypt failed
                        textFieldStyle.normal.textColor  = Color.red;
                        textFieldStyle.focused.textColor = Color.red;

                        // Track that the auto decrypt failed, so we can prevent any editing
                        failedAutoDecrypt = true;
                    }
                }

                EditorGUILayout.BeginHorizontal();

                // The type of player pref being stored (in auto decrypt mode this works with the decrypted values too)
                Type valueType;

                // If it's an encrypted playerpref, we're automatically decrypting and it didn't fail the earlier
                // auto decrypt test
                if (isEncryptedPair && automaticDecryption && !failedAutoDecrypt)
                {
                    // Get the encrypted string
                    string encryptedValue = PlayerPrefs.GetString(fullKey);
                    // Set valueType appropiately based on which type identifier prefix the encrypted string starts with
                    if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_FLOAT_PREFIX))
                    {
                        valueType = typeof(float);
                    }
                    else if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_INT_PREFIX))
                    {
                        valueType = typeof(int);
                    }
                    else if (encryptedValue.StartsWith(PlayerPrefsUtility.VALUE_STRING_PREFIX) || string.IsNullOrEmpty(encryptedValue))
                    {
                        // Special case here, empty encrypted values will also report as strings
                        valueType = typeof(string);
                    }
                    else
                    {
                        throw new InvalidOperationException("Could not decrypt item, no match found in known encrypted key prefixes");
                    }
                }
                else
                {
                    // Otherwise fallback to the type of the cached value (for non-encrypted values this will be
                    // correct). For encrypted values when not in auto-decrypt mode, this will return string type
                    valueType = deserializedValue.GetType();
                }

                // Display the PlayerPref key
                EditorGUILayout.TextField(displayKey, textFieldStyle);

                // Value display and user editing
                // If we're dealing with a float
                if (valueType == typeof(float))
                {
                    float initialValue;
                    if (isEncryptedPair && automaticDecryption)
                    {
                        // Automatically decrypt the value if encrypted and in auto-decrypt mode
                        initialValue = PlayerPrefsUtility.GetEncryptedFloat(displayKey);
                    }
                    else
                    {
                        // Otherwise fetch the latest plain value from PlayerPrefs in memory
                        initialValue = PlayerPrefs.GetFloat(fullKey);
                    }

                    // Display the float editor field and get any changes in value
                    float newValue = EditorGUILayout.FloatField(initialValue, textFieldStyle);

                    // If the value has changed
                    if (newValue != initialValue)
                    {
                        // Store the changed value in player prefs, encrypting if necessary
                        if (isEncryptedPair)
                        {
                            string encryptedValue = PlayerPrefsUtility.VALUE_FLOAT_PREFIX + SimpleEncryption.EncryptFloat(newValue);
                            PlayerPrefs.SetString(fullKey, encryptedValue);
                        }
                        else
                        {
                            PlayerPrefs.SetFloat(fullKey, newValue);
                        }

                        // Save PlayerPrefs
                        PlayerPrefs.Save();
                    }

                    // Display the PlayerPref type
                    GUILayout.Label("float", GUILayout.Width(37));
                }
                else if (valueType == typeof(int)) // if we're dealing with an int
                {
                    int initialValue;
                    if (isEncryptedPair && automaticDecryption)
                    {
                        // Automatically decrypt the value if encrypted and in auto-decrypt mode
                        initialValue = PlayerPrefsUtility.GetEncryptedInt(displayKey);
                    }
                    else
                    {
                        // Otherwise fetch the latest plain value from PlayerPrefs in memory
                        initialValue = PlayerPrefs.GetInt(fullKey);
                    }

                    // Display the int editor field and get any changes in value
                    int newValue = EditorGUILayout.IntField(initialValue, textFieldStyle);

                    // If the value has changed
                    if (newValue != initialValue)
                    {
                        // Store the changed value in player prefs, encrypting if necessary
                        if (isEncryptedPair)
                        {
                            string encryptedValue = PlayerPrefsUtility.VALUE_INT_PREFIX + SimpleEncryption.EncryptInt(newValue);
                            PlayerPrefs.SetString(fullKey, encryptedValue);
                        }
                        else
                        {
                            PlayerPrefs.SetInt(fullKey, newValue);
                        }

                        // Save PlayerPrefs
                        PlayerPrefs.Save();
                    }

                    // Display the PlayerPref type
                    GUILayout.Label("int", GUILayout.Width(37));
                }
                else if (valueType == typeof(string)) // if we're dealing with a string
                {
                    string initialValue;
                    if (isEncryptedPair && automaticDecryption && !failedAutoDecrypt)
                    {
                        // Automatically decrypt the value if encrypted and in auto-decrypt mode
                        initialValue = PlayerPrefsUtility.GetEncryptedString(displayKey);
                    }
                    else
                    {
                        // Otherwise fetch the latest plain value from PlayerPrefs in memory
                        initialValue = PlayerPrefs.GetString(fullKey);
                    }

                    // Display the text (string) editor field and get any changes in value
                    string newValue = EditorGUILayout.TextField(initialValue, textFieldStyle);

                    // If the value has changed
                    if (newValue != initialValue && !failedAutoDecrypt)
                    {
                        // Store the changed value in player prefs, encrypting if necessary
                        if (isEncryptedPair)
                        {
                            string encryptedValue = PlayerPrefsUtility.VALUE_STRING_PREFIX + SimpleEncryption.EncryptString(newValue);
                            PlayerPrefs.SetString(fullKey, encryptedValue);
                        }
                        else
                        {
                            PlayerPrefs.SetString(fullKey, newValue);
                        }

                        // Save PlayerPrefs
                        PlayerPrefs.Save();
                    }

                    if (isEncryptedPair && !automaticDecryption && !string.IsNullOrEmpty(initialValue))
                    {
                        // Because encrypted values when not in auto-decrypt mode are stored as string, determine their
                        // encrypted type and display that instead for these encrypted PlayerPrefs
                        PlayerPrefType playerPrefType = (PlayerPrefType)(int)char.GetNumericValue(initialValue[0]);
                        GUILayout.Label(playerPrefType.ToString().ToLower(), GUILayout.Width(37));
                    }
                    else
                    {
                        // Display the PlayerPref type
                        GUILayout.Label("string", GUILayout.Width(37));
                    }
                }

                // Delete button
                if (GUILayout.Button("X", GUILayout.Width(25)))
                {
                    // Delete the key from player prefs
                    PlayerPrefs.DeleteKey(fullKey);
                    // Tell Unity to Save PlayerPrefs
                    PlayerPrefs.Save();
                    // Delete the cached record so the list updates immediately
                    DeleteCachedRecord(fullKey);
                }

                EditorGUILayout.EndHorizontal();
            }

            // Calculate the padding at the bottom of the scroll view (because only visible player pref rows are drawn)
            float bottomPadding = (entryCount - shownIndexLimit) * rowHeight;

            // If the padding is positive, pad the bottom so that the layout and scroll view size is correct still
            if (bottomPadding > 0)
            {
                GUILayout.Space(bottomPadding);
            }

            EditorGUILayout.EndScrollView();

            // Display the number of player prefs
            GUILayout.Label("Entry Count: " + entryCount);
        }
        private void DrawAddEntry()
        {
            // Create a GUIStyle that can be manipulated for the various text fields
            GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField);

            // Create a space
            EditorGUILayout.Space();

            // Heading
            GUILayout.Label("Add Player Pref", EditorStyles.boldLabel);

            // UI for whether the new player pref is encrypted and what type it is
            EditorGUILayout.BeginHorizontal();
            newEntryIsEncrypted = GUILayout.Toggle(newEntryIsEncrypted, "Encrypt");
            newEntryType        = (PlayerPrefType)GUILayout.SelectionGrid((int)newEntryType, new string[] { "float", "int", "string" }, 3);
            EditorGUILayout.EndHorizontal();

            // Key and Value headings
            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("Key", EditorStyles.boldLabel);
            GUILayout.Label("Value", EditorStyles.boldLabel);
            EditorGUILayout.EndHorizontal();

            // If the new value will be encrypted tint the text boxes blue (in line with the display style for existing
            // encrypted player prefs)
            if (newEntryIsEncrypted)
            {
                if (UsingProSkin)
                {
                    textFieldStyle.normal.textColor  = new Color(0.5f, 0.5f, 1);
                    textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1);
                }
                else
                {
                    textFieldStyle.normal.textColor  = new Color(0, 0, 1);
                    textFieldStyle.focused.textColor = new Color(0, 0, 1);
                }
            }

            EditorGUILayout.BeginHorizontal();

            // Track the next control so we can detect key events in it
            GUI.SetNextControlName("newEntryKey");
            // UI for the new key text box
            newEntryKey = EditorGUILayout.TextField(newEntryKey, textFieldStyle);

            // Track the next control so we can detect key events in it
            GUI.SetNextControlName("newEntryValue");

            // Display the correct UI field editor based on what type of player pref is being created
            if (newEntryType == PlayerPrefType.Float)
            {
                newEntryValueFloat = EditorGUILayout.FloatField(newEntryValueFloat, textFieldStyle);
            }
            else if (newEntryType == PlayerPrefType.Int)
            {
                newEntryValueInt = EditorGUILayout.IntField(newEntryValueInt, textFieldStyle);
            }
            else
            {
                newEntryValueString = EditorGUILayout.TextField(newEntryValueString, textFieldStyle);
            }

            // If the user hit enter while either the key or value fields were being edited
            bool keyboardAddPressed = Event.current.isKey && Event.current.keyCode == KeyCode.Return && Event.current.type == EventType.KeyUp && (GUI.GetNameOfFocusedControl() == "newEntryKey" || GUI.GetNameOfFocusedControl() == "newEntryValue");

            // If the user clicks the Add button or hits return (and there is a non-empty key), create the player pref
            if ((GUILayout.Button("Add", GUILayout.Width(40)) || keyboardAddPressed) && !string.IsNullOrEmpty(newEntryKey))
            {
                // If the player pref we're creating is encrypted
                if (newEntryIsEncrypted)
                {
                    // Encrypt the key
                    string encryptedKey = PlayerPrefsUtility.KEY_PREFIX + SimpleEncryption.EncryptString(newEntryKey);

                    // Note: All encrypted values are stored as string
                    string encryptedValue;

                    // Calculate the encrypted value
                    if (newEntryType == PlayerPrefType.Float)
                    {
                        encryptedValue = PlayerPrefsUtility.VALUE_FLOAT_PREFIX + SimpleEncryption.EncryptFloat(newEntryValueFloat);
                    }
                    else if (newEntryType == PlayerPrefType.Int)
                    {
                        encryptedValue = PlayerPrefsUtility.VALUE_INT_PREFIX + SimpleEncryption.EncryptInt(newEntryValueInt);
                    }
                    else
                    {
                        encryptedValue = PlayerPrefsUtility.VALUE_STRING_PREFIX + SimpleEncryption.EncryptString(newEntryValueString);
                    }

                    // Record the new player pref in PlayerPrefs
                    PlayerPrefs.SetString(encryptedKey, encryptedValue);

                    // Cache the addition
                    CacheRecord(encryptedKey, encryptedValue);
                }
                else
                {
                    if (newEntryType == PlayerPrefType.Float)
                    {
                        // Record the new player pref in PlayerPrefs
                        PlayerPrefs.SetFloat(newEntryKey, newEntryValueFloat);
                        // Cache the addition
                        CacheRecord(newEntryKey, newEntryValueFloat);
                    }
                    else if (newEntryType == PlayerPrefType.Int)
                    {
                        // Record the new player pref in PlayerPrefs
                        PlayerPrefs.SetInt(newEntryKey, newEntryValueInt);
                        // Cache the addition
                        CacheRecord(newEntryKey, newEntryValueInt);
                    }
                    else
                    {
                        // Record the new player pref in PlayerPrefs
                        PlayerPrefs.SetString(newEntryKey, newEntryValueString);
                        // Cache the addition
                        CacheRecord(newEntryKey, newEntryValueString);
                    }
                }

                // Tell Unity to save the PlayerPrefs
                PlayerPrefs.Save();

                // Force a repaint since hitting the return key won't invalidate layout on its own
                Repaint();

                // Reset the values
                newEntryKey         = "";
                newEntryValueFloat  = 0;
                newEntryValueInt    = 0;
                newEntryValueString = "";

                // Deselect
                GUI.FocusControl("");
            }

            EditorGUILayout.EndHorizontal();
        }
Esempio n. 3
0
    private void DrawAddEntry()
    {
        GUIStyle textFieldStyle = new GUIStyle(GUI.skin.textField); // Create a GUIStyle that can be manipulated for the various text fields

        EditorGUILayout.Space();                                    // Create a space
        GUILayout.Label("Add Player Pref", EditorStyles.boldLabel); // Heading

        // UI for whether the new player pref is encrypted and what type it is
        EditorGUILayout.BeginHorizontal();
        newEntryIsEncrypted = GUILayout.Toggle(newEntryIsEncrypted, "Encrypt");
        newEntryType        = (PlayerPrefType)GUILayout.SelectionGrid((int)newEntryType, new string[] { "float", "int", "string", "bool", "Color", "Color32", "Vector2", "Vector3", "Vector4",
                                                                                                        "Quaternion", "Matrix4x4", "Rect", "Bounds" /*,"int[]","string[]", "float[]", "bool[]", "Color[]", "Color32[]", "Vector2[]", "Vector3[]", "Vector4[]", "Quaternion[]",
                                                                                                                                                     * "Matrix4x4[]", "Rect[]", "Bounds[]"*/}, 6);
        EditorGUILayout.EndHorizontal();

        // Key and Value headings
        EditorGUILayout.BeginHorizontal();
        GUILayout.Label("Key", EditorStyles.boldLabel);
        GUILayout.Label("Value", EditorStyles.boldLabel);
        EditorGUILayout.EndHorizontal();

        // If the new value will be encrypted tint the text boxes blue (in line with the display style for existing
        // encrypted player prefs)
        if (newEntryIsEncrypted)
        {
            if (UsingProSkin)
            {
                textFieldStyle.normal.textColor  = new Color(0.5f, 0.5f, 1);
                textFieldStyle.focused.textColor = new Color(0.5f, 0.5f, 1);
            }
            else
            {
                textFieldStyle.normal.textColor  = new Color(0, 0, 1);
                textFieldStyle.focused.textColor = new Color(0, 0, 1);
            }
        }

        EditorGUILayout.BeginHorizontal();


        GUI.SetNextControlName("newEntryKey");                                // Track the next control so we can detect key events in it

        newEntryKey = EditorGUILayout.TextField(newEntryKey, textFieldStyle); // UI for the new key text box


        GUI.SetNextControlName("newEntryValue");// Track the next control so we can detect key events in it

        // Display the correct UI field editor based on what type of player pref is being created

        switch (newEntryType)
        {
        case PlayerPrefType.Float:
            newEntryValueFloat = EditorGUILayout.FloatField(newEntryValueFloat, textFieldStyle);
            break;

        case PlayerPrefType.Int:
            newEntryValueInt = EditorGUILayout.IntField(newEntryValueInt, textFieldStyle);
            break;

        case PlayerPrefType.String:
            newEntryValueString = EditorGUILayout.TextField(newEntryValueString, textFieldStyle);
            break;

        case PlayerPrefType.Bool:
            newEntryValueBool = EditorGUILayout.Toggle(newEntryValueBool);
            break;

        case PlayerPrefType.Color:
            newEntryValueColor = EditorGUILayout.ColorField(newEntryValueColor);
            break;

        case PlayerPrefType.Color32:
            newEntryValueColor32 = EditorGUILayout.ColorField(newEntryValueColor32);
            break;

        case PlayerPrefType.Vector2:
            newEntryValueVector2 = EditorGUILayout.Vector2Field(":Vector2:", newEntryValueVector2);
            break;

        case PlayerPrefType.Vector3:
            newEntryValueVector3 = EditorGUILayout.Vector3Field(":Vector3:", newEntryValueVector3);
            break;

        case PlayerPrefType.Vector4:
            newEntryValueVector4 = EditorGUILayout.Vector4Field(":Vector4:", newEntryValueVector4);
            break;

        case PlayerPrefType.Rect:
            newEntryValueRect = EditorGUILayout.RectField(newEntryValueRect);
            break;

        case PlayerPrefType.Bounds:
            newEntryValueBounds = EditorGUILayout.BoundsField(newEntryValueBounds);
            break;

        case PlayerPrefType.IntArray:


            break;
        }

        //else if (newEntryType == PlayerPrefType.Quaternion) newEntryValueQuaternion = (Quaternion)EditorGUILayout.Vector4Field(":Quaternion:", (Vector4)newEntryValueQuaternion);
        //else if (newEntryType == PlayerPrefType.Matrix4x4) newEntryValueMatrix4x4 = EditorGUILayout.Matrix4x4;


        // If the user hit enter while either the key or value fields were being edited
        bool keyboardAddPressed = Event.current.isKey && Event.current.keyCode == KeyCode.Return && Event.current.type == EventType.KeyUp && (GUI.GetNameOfFocusedControl() == "newEntryKey" || GUI.GetNameOfFocusedControl() == "newEntryValue");

        // If the user clicks the Add button or hits return (and there is a non-empty key), create the player pref
        if ((GUILayout.Button("Add", GUILayout.Width(40)) || keyboardAddPressed) && !string.IsNullOrEmpty(newEntryKey))
        {
            // If the player pref we're creating is encrypted
            if (newEntryIsEncrypted)
            {
                // Encrypt the key
                string encryptedKey = PlayerPrefsUtility.KEY_PREFIX + SimpleEncryption.EncryptString(newEntryKey);

                // Note: All encrypted values are stored as string
                string encryptedValue = string.Empty;

                switch (newEntryType)
                {
                case PlayerPrefType.Float:
                    encryptedValue = PlayerPrefsUtility.floatValuePrefix + SimpleEncryption.EncryptFloat(newEntryValueFloat);
                    break;

                case PlayerPrefType.Int:
                    encryptedValue = PlayerPrefsUtility.intValuePrefix + SimpleEncryption.EncryptInt(newEntryValueInt);
                    break;

                case PlayerPrefType.String:
                    encryptedValue = PlayerPrefsUtility.stringValuePrefix + SimpleEncryption.EncryptString(newEntryValueString);
                    break;

                case PlayerPrefType.Bool:
                    encryptedValue = PlayerPrefsUtility.boolValuePrefix + SimpleEncryption.EncryptString(newEntryValueBool ? "1" : "0");
                    break;

                case PlayerPrefType.Color:
                    encryptedValue = PlayerPrefsUtility.colorValuePrefix + SimpleEncryption.EncryptString(newEntryValueColor.r + "," + newEntryValueColor.g + "," + newEntryValueColor.b + "," + newEntryValueColor.a);
                    break;

                case PlayerPrefType.Color32:
                    encryptedValue = PlayerPrefsUtility.color32ValuePrefix + SimpleEncryption.EncryptString(newEntryValueColor32.r + "," + newEntryValueColor32.g + "," + newEntryValueColor32.b + "," + newEntryValueColor32.a);
                    break;

                case PlayerPrefType.Vector2:
                    encryptedValue = PlayerPrefsUtility.vector2ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector2.x + "," + newEntryValueVector2.y);
                    break;

                case PlayerPrefType.Vector3:
                    encryptedValue = PlayerPrefsUtility.vector3ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector3.x + "," + newEntryValueVector3.y + "," + newEntryValueVector3.z);
                    break;

                case PlayerPrefType.Vector4:
                    encryptedValue = PlayerPrefsUtility.vector4ValuePrefix + SimpleEncryption.EncryptString(newEntryValueVector4.x + "," + newEntryValueVector4.y + "," + newEntryValueVector4.z + "," + newEntryValueVector4.w);
                    break;

                case PlayerPrefType.Quaternion:
                    encryptedValue = PlayerPrefsUtility.quaternionValuePrefix + SimpleEncryption.EncryptString(newEntryValueQuaternion.x + "," + newEntryValueQuaternion.y + "," + newEntryValueQuaternion.z + "," + newEntryValueQuaternion.w);
                    break;

                case PlayerPrefType.Matrix4x4:
                    encryptedValue = PlayerPrefsUtility.quaternionValuePrefix + SimpleEncryption.EncryptString(newEntryValueMatrix4x4.m00 + "," + newEntryValueMatrix4x4.m01 + "," + newEntryValueMatrix4x4.m02 + "," + newEntryValueMatrix4x4.m03 + "," +
                                                                                                               newEntryValueMatrix4x4.m10 + "," + newEntryValueMatrix4x4.m11 + "," + newEntryValueMatrix4x4.m12 + "," + newEntryValueMatrix4x4.m13 + "," +
                                                                                                               newEntryValueMatrix4x4.m20 + "," + newEntryValueMatrix4x4.m21 + "," + newEntryValueMatrix4x4.m22 + "," + newEntryValueMatrix4x4.m23 + "," +
                                                                                                               newEntryValueMatrix4x4.m30 + "," + newEntryValueMatrix4x4.m31 + "," + newEntryValueMatrix4x4.m32 + "," + newEntryValueMatrix4x4.m33 + ",");
                    break;

                case PlayerPrefType.Rect:
                    encryptedValue = PlayerPrefsUtility.rectValuePrefix + SimpleEncryption.EncryptString(newEntryValueRect.x + "," + newEntryValueRect.y + "," + newEntryValueRect.width + "," + newEntryValueRect.height);
                    break;

                case PlayerPrefType.Bounds:
                    encryptedValue = PlayerPrefsUtility.boundsValuePrefix + SimpleEncryption.EncryptString(newEntryValueBounds.center.x + "," + newEntryValueBounds.center.y + "," + newEntryValueBounds.center.z + "," + newEntryValueBounds.extents.x + "," + newEntryValueBounds.extents.y + "," + newEntryValueBounds.extents.z);
                    break;
                }

                // Calculate the encrypted value

                // Record the new player pref in PlayerPrefs
                PlayerPrefs.SetString(encryptedKey, encryptedValue);

                // Cache the addition
                CacheRecord(encryptedKey, encryptedValue);
            }
            else
            {
                switch (newEntryType)
                {
                case PlayerPrefType.Float:
                    PlayerPrefs.SetFloat(newEntryKey, newEntryValueFloat); // Record the new player pref in PlayerPrefs
                    CacheRecord(newEntryKey, newEntryValueFloat);          // Cache the addition
                    break;

                case PlayerPrefType.Int:
                    PlayerPrefs.SetInt(newEntryKey, newEntryValueInt); // Record the new player pref in PlayerPrefs
                    CacheRecord(newEntryKey, newEntryValueInt);        // Cache the addition
                    break;

                case PlayerPrefType.String:
                    PlayerPrefs.SetString(newEntryKey, newEntryValueString); // Record the new player pref in PlayerPrefs
                    CacheRecord(newEntryKey, newEntryValueString);           // Cache the addition
                    break;

                case PlayerPrefType.Bool:
                    PlayerPrefsUtility.SetBool(newEntryKey, newEntryValueBool);
                    CacheRecord(newEntryKey, newEntryValueBool);
                    break;

                case PlayerPrefType.Color:
                    PlayerPrefsUtility.SetColor(newEntryKey, newEntryValueColor);
                    CacheRecord(newEntryKey, newEntryValueColor);
                    break;

                case PlayerPrefType.Color32:
                    PlayerPrefsUtility.SetColor32(newEntryKey, newEntryValueColor32);
                    CacheRecord(newEntryKey, newEntryValueColor32);
                    break;

                case PlayerPrefType.Vector2:
                    PlayerPrefsUtility.SetVector2(newEntryKey, newEntryValueVector2);
                    CacheRecord(newEntryKey, newEntryValueVector2);
                    break;

                case PlayerPrefType.Vector3:
                    PlayerPrefsUtility.SetVector3(newEntryKey, newEntryValueVector3);
                    CacheRecord(newEntryKey, newEntryValueVector3);
                    break;

                case PlayerPrefType.Vector4:
                    PlayerPrefsUtility.SetVector4(newEntryKey, newEntryValueVector4);
                    CacheRecord(newEntryKey, newEntryValueVector4);
                    break;

                case PlayerPrefType.Quaternion:
                    PlayerPrefsUtility.SetQuaternion(newEntryKey, newEntryValueQuaternion);
                    CacheRecord(newEntryKey, newEntryValueQuaternion);
                    break;

                case PlayerPrefType.Matrix4x4:
                    PlayerPrefsUtility.SetMatrix4x4(newEntryKey, newEntryValueMatrix4x4);
                    CacheRecord(newEntryKey, newEntryValueMatrix4x4);
                    break;

                case PlayerPrefType.Rect:
                    PlayerPrefsUtility.SetRect(newEntryKey, newEntryValueRect);
                    CacheRecord(newEntryKey, newEntryValueRect);
                    break;

                case PlayerPrefType.Bounds:
                    PlayerPrefsUtility.SetBounds(newEntryKey, newEntryValueBounds);
                    CacheRecord(newEntryKey, newEntryValueBounds);
                    break;
                }
            }

            // Tell Unity to save the PlayerPrefs
            PlayerPrefs.Save();

            // Force a repaint since hitting the return key won't invalidate layout on its own
            Repaint();

            // Reset the values
            newEntryKey         = "";
            newEntryValueFloat  = 0;
            newEntryValueInt    = 0;
            newEntryValueString = "";

            // Deselect
            GUI.FocusControl("");
        }

        EditorGUILayout.EndHorizontal();
    }