int BoolField(SerializedProperty sp, InspectorPlusVar v)
    {
        if (v.toggleStart)
        {
            EditorGUI.BeginProperty(new Rect(0.0f, 0.0f, 0.0f, 0.0f), new GUIContent(), sp);

            EditorGUI.BeginChangeCheck();
            var newValue = EditorGUILayout.Toggle(dispName, sp.boolValue);

            if (EditorGUI.EndChangeCheck())
            {
                sp.boolValue = newValue;
            }

            EditorGUI.EndProperty();

            if (!sp.boolValue)
            {
                return(v.toggleSize);
            }
        }
        else
        {
            EditorGUILayout.PropertyField(sp, new GUIContent(dispName));
        }

        return(0);
    }
    void FloatField(SerializedProperty sp, InspectorPlusVar v)
    {
        if (v.limitType == InspectorPlusVar.LimitType.Min && !sp.hasMultipleDifferentValues)
        {
            sp.floatValue = Mathf.Max(v.min, sp.floatValue);
        }
        else if (v.limitType == InspectorPlusVar.LimitType.Max && !sp.hasMultipleDifferentValues)
        {
            sp.floatValue = Mathf.Min(v.max, sp.floatValue);
        }

        if (v.limitType == InspectorPlusVar.LimitType.Range)
        {
            if (!v.progressBar)
            {
                EditorGUILayout.Slider(sp, v.min, v.max);
            }
            else
            {
                if (!sp.hasMultipleDifferentValues)
                {
                    sp.floatValue = Mathf.Clamp(sp.floatValue, v.min, v.max);
                    ProgressBar((sp.floatValue - v.min) / v.max, dispName);
                }
                else
                {
                    ProgressBar((sp.floatValue - v.min) / v.max, dispName);
                }
            }
        }
        else
        {
            EditorGUILayout.PropertyField(sp, new GUIContent(dispName));
        }
    }
    public override void OnInspectorGUI()
    {
        so.Update();
        RefreshVars();

        // EditorGUIUtility.LookLikeControls (135.0f, 50.0f);
        EditorGUIUtility.labelWidth = 135;
        EditorGUIUtility.fieldWidth = 50;

        for (int i = 0; i < properties.Length; i += 1)
        {
            InspectorPlusVar v = vars[i];

            if (v.active && properties[i] != null)
            {
                SerializedProperty sp = properties [i]; string s = v.type;
                bool skip = false;
                name     = v.name;
                dispName = v.dispName;

                GUI.enabled = v.canWrite;

                GUILayout.BeginHorizontal();

                if (v.toggleLevel != 0)
                {
                    GUILayout.Space(v.toggleLevel * 10.0f);
                }

                if (s == typeof(float).Name)
                {
                    FloatField(sp, v);
                    skip = true;
                }
                if (s == typeof(bool).Name)
                {
                    i   += BoolField(sp, v);
                    skip = true;
                }
                if (!skip)
                {
                    PropertyField(sp, name);
                }
                GUILayout.EndHorizontal();
                GUI.enabled = true;
                if (v.hasTooltip)
                {
                    Rect last = GUILayoutUtility.GetLastRect();
                    GUI.Label(last, new GUIContent("", v.tooltip));

                    GUIStyle style = new GUIStyle();
                    style.fixedWidth = 250.0f;
                    style.wordWrap   = true;

                    Vector2 size = new GUIStyle().CalcSize(new GUIContent(GUI.tooltip));
                    tooltipRect = new Rect(Event.current.mousePosition.x + 4.0f, Event.current.mousePosition.y + 12.0f, 28.0f + size.x, 9.0f + size.y);

                    if (tooltipRect.width > 250.0f)
                    {
                        float delt = (tooltipRect.width - 250.0f);
                        tooltipRect.width  -= delt;
                        tooltipRect.height += size.y * Mathf.CeilToInt(delt / 250.0f);
                    }
                }
            }
            if (v.space == 0.0f)
            {
                continue;
            }
            float usedSpace = 0.0f;
            for (int j = 0; j < v.numSpace; j += 1)
            {
                if (v.labelEnabled [j] || v.buttonEnabled [j])
                {
                    usedSpace += 18.0f;
                }
            }
            if (v.space == 0.0f)
            {
                continue;
            }
            float space = Mathf.Max(0.0f, (v.space - usedSpace) / 2.0f);
            GUILayout.Space(space);
            for (int j = 0; j < v.numSpace; j += 1)
            {
                bool buttonLine = false;
                for (int k = 0; k < 4; k += 1)
                {
                    if (v.buttonEnabled[j * 4 + k])
                    {
                        buttonLine = true;
                    }
                }
                if (!v.labelEnabled[j] && !buttonLine)
                {
                    continue;
                }


                GUILayout.BeginHorizontal();
                if (v.labelEnabled[j])
                {
                    GUIStyle boldItalic = new GUIStyle();
                    boldItalic.margin = new RectOffset(5, 5, 5, 5);

                    if (v.labelAlign[j] == 0)
                    {
                        boldItalic.alignment = TextAnchor.MiddleLeft;
                    }
                    else if (v.labelAlign[j] == 1)
                    {
                        boldItalic.alignment = TextAnchor.MiddleCenter;
                    }
                    else if (v.labelAlign[j] == 2)
                    {
                        boldItalic.alignment = TextAnchor.MiddleRight;
                    }

                    if (v.labelBold[j] && v.labelItalic[j])
                    {
                        boldItalic.fontStyle = FontStyle.BoldAndItalic;
                    }
                    else if (v.labelBold[j])
                    {
                        boldItalic.fontStyle = FontStyle.Bold;
                    }
                    else if (v.labelItalic[j])
                    {
                        boldItalic.fontStyle = FontStyle.Italic;
                    }

                    GUILayout.Label(v.label[j], boldItalic);
                    boldItalic.alignment = TextAnchor.MiddleLeft;
                }
                bool alignRight = (v.labelEnabled[j] && buttonLine);

                if (!alignRight)
                {
                    GUILayout.EndHorizontal();
                    GUILayout.BeginHorizontal();
                }

                GUILayout.FlexibleSpace();
                for (int k = 0; k < 4; k += 1)
                {
                    if (v.buttonEnabled[j * 4 + k])
                    {
                        if (!v.buttonCondense[j] && !alignRight)
                        {
                            GUILayout.FlexibleSpace();
                        }

                        string style = "Button";
                        if (v.buttonCondense[j])
                        {
                            bool hasLeft  = false;
                            bool hasRight = false;
                            for (int p = k - 1; p >= 0; p -= 1)
                            {
                                if (v.buttonEnabled[j * 4 + p])
                                {
                                    hasLeft = true;
                                }
                            }
                            for (int p = k + 1; p < 4; p += 1)
                            {
                                if (v.buttonEnabled[j * 4 + p])
                                {
                                    hasRight = true;
                                }
                            }

                            if (!hasLeft && hasRight)
                            {
                                style = "ButtonLeft";
                            }
                            else if (hasLeft && hasRight)
                            {
                                style = "ButtonMid";
                            }
                            else if (hasLeft && !hasRight)
                            {
                                style = "ButtonRight";
                            }
                            else if (!hasLeft && !hasRight)
                            {
                                style = "Button";
                            }
                        }

                        if (GUILayout.Button(v.buttonText[j * 4 + k], style, GUILayout.MinWidth(60.0f)))
                        {
                            foreach (object t in targets)
                            {
                                MethodInfo m = t.GetType().GetMethod(v.buttonCallback[j * 4 + k], BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic);
                                if (m != null)
                                {
                                    m.Invoke(target, null);
                                }
                            }
                        }

                        if (!v.buttonCondense[j] && !alignRight)
                        {
                            GUILayout.FlexibleSpace();
                        }
                    }
                }
                GUILayout.FlexibleSpace();
                GUILayout.EndHorizontal();
            }
            GUILayout.Space(space);
        }
        so.ApplyModifiedProperties();
        if (!string.IsNullOrEmpty(GUI.tooltip))
        {
            GUI.color = new Color(1.0f, 1.0f, 1.0f, 1.0f);
            GUI.Box(tooltipRect, new GUIContent());
            EditorGUI.HelpBox(tooltipRect, GUI.tooltip, MessageType.Info);
            Repaint();
        }
        GUI.tooltip = "";
    }