private void Init(string title)
        {
            this.StyleFont(FontStyle.Bold);
            this.StyleMinHeight(20);
            this.StyleBorderWidth(0, 0, 1, 0);
            Color borderColor = EditorGUIUtility.isProSkin
                ? new Color32(35, 35, 35, 255)
                : new Color32(153, 153, 153, 255);

            this.StyleBorderColor(borderColor);

            headerElement = new HorizontalLayout();
            headerElement.StyleHeight(21);
            headerElement.StyleMaxHeight(21);
            headerElement.StyleMinHeight(21);
            headerElement.StylePadding(4, 0, 0, 0);
            headerElement.StyleAlignItem(Align.Center);
            Color backgroundColor = EditorGUIUtility.isProSkin
                ? new Color32(80, 80, 80, 255)
                : new Color32(222, 222, 222, 255);

            headerElement.StyleBackgroundColor(backgroundColor);
            Color hoverBorderColor = new Color32(58, 121, 187, 255);

            headerElement.RegisterCallback <MouseEnterEvent>((evt) =>
            {
                headerElement.StyleBorderWidth(1);
                headerElement.StyleBorderColor(hoverBorderColor);
            });
            headerElement.RegisterCallback <MouseLeaveEvent>((evt) =>
            {
                headerElement.StyleBorderWidth(0);
                headerElement.StyleBorderColor(Color.clear);
            });
            base.Add(headerElement);

            contentElement = new VerticalLayout();
            contentElement.StyleDisplay(value);
            base.Add(contentElement);

            labelElement      = new Label();
            labelElement.text = title;
            headerElement.Add(labelElement);

            imageElement      = new Image();
            imageElement.name = nameof(imageElement);
            imageElement.StyleMargin(0, 4, 0, 0);
            imageElement.StyleSize(16, 16);
            headerElement.Add(imageElement);
            imageElement.SendToBack();
            imageElement.RegisterCallback <GeometryChangedEvent>((evt) =>
            {
                imageElement.StyleDisplay(imageElement.image == null ? DisplayStyle.None : DisplayStyle.Flex);
            });

            foloutImage = new Image();
            foloutImage.StyleWidth(13);
            foloutImage.StyleMargin(0, 2, 0, 0);
            foloutImage.scaleMode = ScaleMode.ScaleToFit;
            foloutImage.image     = value ? onIcon : offIcon;
            if (!EditorGUIUtility.isProSkin)
            {
                foloutImage.tintColor = Color.grey;
            }
            headerElement.Add(foloutImage);
            foloutImage.SendToBack();


            headerElement.RegisterCallback <MouseUpEvent>((evt) =>
            {
                if (evt.button == 0)
                {
                    Value = !Value;
                    evt.StopPropagation();
                }
            });
        }
        // bool registerCallbackToParent = false;

        public VisualWindow()
        {
            this.StyleBorderRadius(4, 4, 4, 4);
            this.StyleBorderWidth(1, 1, 2, 2);
            Color borderColor = new Color32(58, 121, 187, 255);

            this.StyleBorderColor(Color.grey, Color.grey, borderColor, borderColor);
            Color backgroundColor = EditorGUIUtility.isProSkin
                ? new Color32(64, 64, 64, 255)
                : new Color32(184, 184, 184, 255);

            this.StyleBackgroundColor(backgroundColor);
            this.StyleMinSize(128, 32);
            this.StyleMaxSize(9999, 9999);
            this.StylePosition(Position.Absolute);
            this.AddManipulator(new UIDragger(this, true));

            this.RegisterCallback <MouseOverEvent>(RegisterParentGeometryChanged);


            headerElement      = new HorizontalLayout();
            headerElement.name = nameof(headerElement).ToUpper();
            headerElement.StyleMaxHeight(24);
            headerElement.StyleMinHeight(24);
            headerElement.StylePadding(18, 18, 4, 4);
            headerElement.StyleJustifyContent(Justify.Center);
            headerElement.RegisterCallback <MouseUpEvent>((callback) =>
            {
                if (callback.button == 2)
                {
                    this.style.width = this.style.height = StyleKeyword.Auto;
                    Repaint();
                }
            });
            base.Add(headerElement);

            labelElement      = new Label();
            labelElement.name = nameof(labelElement).ToUpper();
            name = labelElement.text = "Untitled";
            labelElement.StyleMargin(0, 0, 0, 2);
            labelElement.StyleAlignSelf(Align.Center);
            labelElement.StyleFont(FontStyle.Bold);
            headerElement.Add(labelElement);

            Image closeButton = new Image();

            closeButton.name  = nameof(closeButton).ToUpper();
            closeButton.image = EditorGUIUtility.IconContent("winbtn_win_close").image;
            closeButton.StyleSize(16, 16);
            closeButton.StyleBorderWidth(1, 0, 0, 1);
            closeButton.StyleBorderRadius(0, 0, 4, 0);
            closeButton.StyleBorderColor(borderColor);
            closeButton.StylePosition(Position.Absolute);
            closeButton.StyleAlignSelf(Align.FlexEnd);
            base.Add(closeButton);

            closeButton.RegisterCallback <MouseDownEvent>((e) => { this.StyleDisplay(DisplayStyle.None); });

            contentElement      = new VisualElement();
            contentElement.name = nameof(contentElement).ToUpper();
            contentElement.StyleMargin(0, 0, 0, 9);
            base.Add(contentElement);

            Image resizeButton = new Image();

            resizeButton.name = nameof(resizeButton).ToUpper();
            resizeButton.StyleAlignSelf(Align.FlexEnd);
            resizeButton.StylePosition(Position.Absolute);
            resizeButton.StyleSize(8, 8);
            resizeButton.StyleBorderRadius(0, 0, 0, 4);
            resizeButton.StyleBorderWidth(0, 2, 0, 2);
            resizeButton.StyleBorderColor(Color.grey);
            resizeButton.StyleRight(1);
            resizeButton.StyleBottom(1);
            base.Add(resizeButton);
            var uIResizer = new UIResizer(this);

            resizeButton.AddManipulator(uIResizer);
            uIResizer.mouseMoveAction += () =>
            {
                resizeButton.StyleRight(1);
                resizeButton.StyleBottom(1);
            };
        }
        static SettingsProvider UIElementSettingsProvider()
        {
            var provider = new SettingsProvider("Project/Hierarchy", SettingsScope.Project)
            {
                label = "Hierarchy",

                activateHandler = (searchContext, rootElement) =>
                {
                    var settings = GetAssets();

                    float TITLE_MARGIN_TOP    = 14;
                    float TITLE_MARGIN_BOTTOM = 8;
                    float CONTENT_MARGIN_LEFT = 10;

                    HorizontalLayout horizontalLayout = new HorizontalLayout();
                    horizontalLayout.style.backgroundColor = new Color(0, 0, 0, 0.2f);
                    horizontalLayout.style.paddingTop      = 4;
                    horizontalLayout.style.paddingBottom   = 10;
                    rootElement.Add(horizontalLayout);

                    Label hierarchyTitle = new Label("Hierarchy");
                    hierarchyTitle.StyleFontSize(20);
                    hierarchyTitle.StyleMargin(10, 0, 2, 2);
                    hierarchyTitle.StyleFont(FontStyle.Bold);
                    horizontalLayout.Add(hierarchyTitle);

                    Label importButton = new Label();
                    importButton.text = "  Import";
                    importButton.style.unityFontStyleAndWeight = FontStyle.Italic;
                    Color importExportButtonColor = new Color32(102, 157, 246, 255);
                    importButton.style.color = importExportButtonColor;
                    importButton.RegisterCallback <PointerUpEvent>(evt => instance.ImportFromJson());
                    horizontalLayout.Add(importButton);

                    Label exportButton = new Label();
                    exportButton.text = "| Export";
                    exportButton.style.unityFontStyleAndWeight = FontStyle.Italic;
                    exportButton.style.color = importExportButtonColor;
                    exportButton.RegisterCallback <PointerUpEvent>(evt => instance.ExportToJson());
                    horizontalLayout.Add(exportButton);

                    ScrollView scrollView = new ScrollView();
                    rootElement.Add(scrollView);

                    VerticalLayout verticalLayout = new VerticalLayout();
                    verticalLayout.StylePadding(8, 8, 8, 8);
                    scrollView.Add(verticalLayout);

                    var Object = new Label("Object");
                    Object.StyleFont(FontStyle.Bold);
                    Object.StyleMargin(0, 0, 0, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(Object);

                    var displayCustomObjectIcon = new Toggle("Display Custom Icon");
                    displayCustomObjectIcon.value = settings.displayCustomObjectIcon;
                    displayCustomObjectIcon.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayCustomObjectIcon = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayCustomObjectIcon));
                    });
                    displayCustomObjectIcon.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayCustomObjectIcon);

                    var View = new Label("View");
                    View.StyleFont(FontStyle.Bold);
                    View.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(View);

                    var displayRowBackground = new Toggle("Display RowBackground");
                    displayRowBackground.value = settings.displayRowBackground;
                    displayRowBackground.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayRowBackground = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayRowBackground));
                    });
                    displayRowBackground.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayRowBackground);

                    var displayTreeView = new Toggle("Display TreeView");
                    displayTreeView.value = settings.displayTreeView;
                    displayTreeView.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayTreeView = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayTreeView));
                    });
                    displayTreeView.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayTreeView);

                    var displayGrid = new Toggle("Display Grid");
                    displayGrid.value = settings.displayGrid;
                    displayGrid.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayGrid = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayGrid));
                    });
                    displayGrid.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayGrid);

                    var Components = new Label("Components");
                    Components.StyleFont(FontStyle.Bold);
                    Components.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(Components);

                    var displayComponents = new Toggle("Display Components Icon");
                    displayComponents.value = settings.displayComponents;
                    displayComponents.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayComponents = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayComponents));
                    });
                    displayComponents.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayComponents);

                    var componentAlignment = new EnumField(settings.componentAlignment);
                    componentAlignment.label = "Component Alignment";
                    componentAlignment.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.componentAlignment = (ElementAlignment)evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.componentAlignment));
                    });
                    componentAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(componentAlignment);

                    var componentDisplayMode = new EnumField(settings.componentDisplayMode);
                    componentDisplayMode.label = "Component Display Mode";
                    componentDisplayMode.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(componentDisplayMode);

                    var componentListInput = new TextField("Components");
                    componentListInput.value = string.Join(" ", settings.components);
                    componentListInput.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(componentListInput);
                    componentListInput.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.components = evt.newValue.Split(' ');
                        settings.OnSettingsChanged(nameof(settings.components));
                    });
                    componentDisplayMode.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.componentDisplayMode = (ComponentDisplayMode)evt.newValue;
                        switch (settings.componentDisplayMode)
                        {
                        case ComponentDisplayMode.Specified:
                            componentListInput.StyleDisplay(true);
                            break;

                        case ComponentDisplayMode.Ignore:
                            componentListInput.StyleDisplay(true);
                            break;

                        case ComponentDisplayMode.All:
                            componentListInput.StyleDisplay(false);
                            break;

                        case ComponentDisplayMode.ScriptOnly:
                            componentListInput.StyleDisplay(false);
                            break;
                        }

                        settings.OnSettingsChanged(nameof(settings.componentDisplayMode));
                    });

                    var componentSizeEnum = ComponentSize.Normal;
                    switch (settings.componentSize)
                    {
                    case 12:
                        componentSizeEnum = ComponentSize.Small;
                        break;

                    case 14:
                        componentSizeEnum = ComponentSize.Normal;
                        break;

                    case 16:
                        componentSizeEnum = ComponentSize.Large;
                        break;
                    }

                    var componentSize = new EnumField(componentSizeEnum);
                    componentSize.label = "Component Size";
                    componentSize.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    componentSize.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        switch (evt.newValue)
                        {
                        case ComponentSize.Small:
                            settings.componentSize = 12;
                            break;

                        case ComponentSize.Normal:
                            settings.componentSize = 14;
                            break;

                        case ComponentSize.Large:
                            settings.componentSize = 16;
                            break;
                        }

                        settings.OnSettingsChanged(nameof(settings.componentSize));
                    });
                    verticalLayout.Add(componentSize);

                    var componentSpacing = new IntegerField();
                    componentSpacing.label = "Component Spacing";
                    componentSpacing.value = settings.componentSpacing;
                    componentSpacing.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    componentSpacing.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.componentSpacing = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.componentSpacing));
                    });
                    verticalLayout.Add(componentSpacing);

                    var TagAndLayer = new Label("Tag And Layer");
                    TagAndLayer.StyleFont(FontStyle.Bold);
                    TagAndLayer.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(TagAndLayer);

                    var displayTag = new Toggle("Display Tag");
                    displayTag.value = settings.displayTag;
                    displayTag.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayTag = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayTag));
                    });
                    displayTag.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayTag);

                    var applyTagTargetAndChild = new Toggle("Tag Recursive Change");
                    applyTagTargetAndChild.value = settings.applyTagTargetAndChild;
                    applyTagTargetAndChild.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.applyTagTargetAndChild = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.applyTagTargetAndChild));
                    });
                    applyTagTargetAndChild.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(applyTagTargetAndChild);

                    var tagAlignment = new EnumField(settings.tagAlignment);
                    tagAlignment.label = "Tag Alignment";
                    tagAlignment.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.tagAlignment = (ElementAlignment)evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.tagAlignment));
                    });
                    tagAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(tagAlignment);

                    var displayLayer = new Toggle("Display Layer");
                    displayLayer.value = settings.displayLayer;
                    displayLayer.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.displayLayer = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.displayLayer));
                    });
                    displayLayer.style.marginTop = 8;
                    displayLayer.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(displayLayer);

                    var applyLayerTargetAndChild = new Toggle("Layer Recursive Change");
                    applyLayerTargetAndChild.value = settings.applyLayerTargetAndChild;
                    applyLayerTargetAndChild.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.applyLayerTargetAndChild = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.applyLayerTargetAndChild));
                    });
                    applyLayerTargetAndChild.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(applyLayerTargetAndChild);

                    var layerAlignment = new EnumField(settings.layerAlignment);
                    layerAlignment.label = "Layer Alignment";
                    layerAlignment.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.layerAlignment = (ElementAlignment)evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.layerAlignment));
                    });
                    layerAlignment.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(layerAlignment);

                    var advanced = new Label("Advanced");
                    advanced.StyleFont(FontStyle.Bold);
                    advanced.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(advanced);

                    var separatorStartWith = new TextField();
                    separatorStartWith.label = "Separator StartWith";
                    separatorStartWith.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    separatorStartWith.value = settings.separatorStartWith;
                    separatorStartWith.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.separatorStartWith = evt.newValue == String.Empty ? "--->" : evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.separatorStartWith));
                    });
                    verticalLayout.Add(separatorStartWith);

                    var headerDefaultTag = new TagField();
                    headerDefaultTag.label = "Separator Default Tag";
                    headerDefaultTag.value = settings.separatorDefaultTag;
                    headerDefaultTag.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.separatorDefaultTag = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.separatorDefaultTag));
                    });
                    headerDefaultTag.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    headerDefaultTag.StyleMarginBottom(4);
                    verticalLayout.Add(headerDefaultTag);

                    IMGUIContainer instantBackgroundIMGUI = new IMGUIContainer(() =>
                    {
                        EditorGUILayout.BeginHorizontal();
                        settings.useInstantBackground = EditorGUILayout.Toggle("Use Instant Background", settings.useInstantBackground);
                        EditorGUILayout.BeginVertical("helpbox");
                        EditorGUILayout.PropertyField(new SerializedObject(settings).FindProperty(nameof(instantBackgroundColors)), GUIContent.none);
                        EditorGUILayout.EndVertical();
                        EditorGUILayout.EndHorizontal();
                    });
                    instantBackgroundIMGUI.StyleMarginTop(7);
                    instantBackgroundIMGUI.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(instantBackgroundIMGUI);

                    var onlyDisplayWhileMouseHovering = new Toggle("Display Hovering");
                    onlyDisplayWhileMouseHovering.tooltip = "Only display while mouse hovering";
                    onlyDisplayWhileMouseHovering.StyleMarginTop(7);
                    onlyDisplayWhileMouseHovering.value = settings.onlyDisplayWhileMouseEnter;
                    onlyDisplayWhileMouseHovering.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.onlyDisplayWhileMouseEnter = evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.onlyDisplayWhileMouseEnter));
                    });
                    onlyDisplayWhileMouseHovering.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                    verticalLayout.Add(onlyDisplayWhileMouseHovering);

                    var contentMaskEnumFlags = new EnumFlagsField(settings.contentDisplay);
                    contentMaskEnumFlags.StyleDisplay(onlyDisplayWhileMouseHovering.value);
                    contentMaskEnumFlags.label = "Content Mask";
                    onlyDisplayWhileMouseHovering.RegisterValueChangedCallback((evt) => { contentMaskEnumFlags.StyleDisplay(evt.newValue); });
                    contentMaskEnumFlags.RegisterValueChangedCallback((evt) =>
                    {
                        Undo.RecordObject(settings, "Change Settings");

                        settings.contentDisplay = (ContentDisplay)evt.newValue;
                        settings.OnSettingsChanged(nameof(settings.contentDisplay));
                    });
                    contentMaskEnumFlags.style.marginLeft = CONTENT_MARGIN_LEFT;
                    verticalLayout.Add(contentMaskEnumFlags);

                    var Theme = new Label("Theme");
                    Theme.StyleFont(FontStyle.Bold);
                    Theme.StyleMargin(0, 0, TITLE_MARGIN_TOP, TITLE_MARGIN_BOTTOM);
                    verticalLayout.Add(Theme);

                    if (EditorApplication.isPlayingOrWillChangePlaymode)
                    {
                        EditorHelpBox themeWarningPlaymode =
                            new EditorHelpBox("This setting only available on edit mode.", MessageType.Info);
                        verticalLayout.Add(themeWarningPlaymode);
                    }
                    else
                    {
                        EditorHelpBox selectionColorHelpBox = new EditorHelpBox(
                            "Theme selection color require editor assembly recompile to take affect.\nBy selecting any script, right click -> Reimport. it will force the editor to recompile.",
                            MessageType.Info);
                        selectionColorHelpBox.StyleDisplay(false);
                        verticalLayout.Add(selectionColorHelpBox);

                        ColorField colorRowEven = new ColorField("Row Even");
                        colorRowEven.value = settings.usedTheme.colorRowEven;
                        colorRowEven.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorRowEven.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorRowEven = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorRowEven = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorRowEven);

                        ColorField colorRowOdd = new ColorField("Row Odd");
                        colorRowOdd.value = settings.usedTheme.colorRowOdd;
                        colorRowOdd.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorRowOdd.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorRowOdd = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorRowOdd = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorRowOdd);

                        ColorField colorGrid = new ColorField("Grid Color");
                        colorGrid.value = settings.usedTheme.colorGrid;
                        colorGrid.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorGrid.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorGrid = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorGrid = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorGrid);

                        ColorField colorTreeView = new ColorField("TreeView");
                        colorTreeView.value = settings.usedTheme.colorTreeView;
                        colorTreeView.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorTreeView.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorTreeView = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorTreeView = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorTreeView);

                        ColorField colorLockIcon = new ColorField("Lock Icon");
                        colorLockIcon.value = settings.usedTheme.colorLockIcon;
                        colorLockIcon.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorLockIcon.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorLockIcon = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorLockIcon = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorLockIcon);

                        ColorField tagColor = new ColorField("Tag Text");
                        tagColor.value = settings.usedTheme.tagColor;
                        tagColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        tagColor.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.tagColor = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.tagColor = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(tagColor);

                        ColorField layerColor = new ColorField("Layer Text");
                        layerColor.value = settings.usedTheme.layerColor;
                        layerColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        layerColor.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.layerColor = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.layerColor = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(layerColor);

                        ColorField colorHeaderTitle = new ColorField("Header Title");
                        colorHeaderTitle.value = settings.usedTheme.colorHeaderTitle;
                        colorHeaderTitle.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorHeaderTitle.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorHeaderTitle = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorHeaderTitle = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorHeaderTitle);

                        ColorField colorHeaderBackground = new ColorField("Header Background");
                        colorHeaderBackground.value = settings.usedTheme.colorHeaderBackground;
                        colorHeaderBackground.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        colorHeaderBackground.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.colorHeaderBackground = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.colorHeaderBackground = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(colorHeaderBackground);

                        ColorField comSelBGColor = new ColorField("Component Selection");
                        comSelBGColor.value = settings.usedTheme.comSelBGColor;
                        comSelBGColor.StyleMarginLeft(CONTENT_MARGIN_LEFT);
                        comSelBGColor.RegisterValueChangedCallback((evt) =>
                        {
                            Undo.RecordObject(settings, "Change Settings");

                            if (EditorGUIUtility.isProSkin)
                            {
                                settings.professionalTheme.comSelBGColor = evt.newValue;
                            }
                            else
                            {
                                settings.personalTheme.comSelBGColor = evt.newValue;
                            }

                            settings.OnSettingsChanged();
                        });
                        verticalLayout.Add(comSelBGColor);
                    }

                    Undo.undoRedoPerformed -= OnUndoRedoPerformed;
                    Undo.undoRedoPerformed += OnUndoRedoPerformed;
                },

                deactivateHandler = () => Undo.undoRedoPerformed -= OnUndoRedoPerformed,

                keywords = new HashSet <string>(new[] { "Hierarchy" })
            };

            return(provider);
        }