// Render item element "active by default" toggle
        private void RenderListItemActiveByDefault(List <UiLayoutPreset> list, UiLayoutPreset item, ItemType type)
        {
            if (type != ItemType.Popup)
            {
                // Active by default
                EditorGUI.BeginChangeCheck();
                item.ActiveByDefault = EditorGUILayout.Toggle("Active by default", item.ActiveByDefault);
                if (EditorGUI.EndChangeCheck())
                {
                    InternalUtilities.SetDirty(target);

                    if (type == ItemType.Screen)
                    {
                        OnItemSetActiveByDefault(list, item, item.ActiveByDefault);
                    }
                }

                // Skip animation
                if (item.ActiveByDefault)
                {
                    EditorGUI.BeginChangeCheck();
                    item.ActiveByDefaultImmediately = EditorGUILayout.Toggle("Skip animation", item.ActiveByDefaultImmediately);
                    if (EditorGUI.EndChangeCheck())
                    {
                        InternalUtilities.SetDirty(target);
                    }
                }
            }
        }
        public override void OnInspectorGUI()
        {
            UiLayoutSettings layoutSettings = target as UiLayoutSettings;

            GUIStyle style = new GUIStyle(GUI.skin.GetStyle("HelpBox"));

            style.padding = new RectOffset(7, 7, 7, 7);

            GUILayout.BeginVertical(style);
            layoutSettings.DefaultContainer = (RectTransform)EditorGUILayout.ObjectField("Default Container", layoutSettings.DefaultContainer, typeof(RectTransform), allowSceneObjects: true);
            GUILayout.EndVertical();

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Screens Presets");
            _dynamicItemSelected = RenderList(layoutSettings.Screens, _dynamicItemSelected, ItemType.Screen);

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Panels Presets");
            _staticItemSelected = RenderList(layoutSettings.Panels, _staticItemSelected, ItemType.Panel);

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Popups Presets");
            _popupItemSelected = RenderList(layoutSettings.Popups, _popupItemSelected, ItemType.Popup);

            EditorGUILayout.Space();

            EditorGUILayout.LabelField("Custom Signals");
            RenderSignals();

            EditorGUILayout.Space();
        }
        // Render item element signals fields
        private void RenderListItemSignals(List <UiLayoutPreset> list, UiLayoutPreset item, ItemType type)
        {
            InternalLayout.ButtonSignals
            (
                "Show on signals",
                "Select signals to show " + GetItemPrefabName(item),
                item.SignalsShow,
                (string[] result) =>
            {
                item.SignalsShow = result;
                Repaint();
            }
            );

            InternalLayout.ButtonSignals
            (
                "Hide on signals",
                "Select signals to hide " + GetItemPrefabName(item),
                item.SignalsHide,
                (string[] result) =>
            {
                item.SignalsHide = result;
                Repaint();
            }
            );
        }
 // Render item element container field
 private void RenderListItemContainer(List <UiLayoutPreset> list, UiLayoutPreset item, ItemType type)
 {
     EditorGUI.BeginChangeCheck();
     item.Container = (RectTransform)EditorGUILayout.ObjectField("Container", item.Container, typeof(RectTransform), allowSceneObjects: true);
     if (EditorGUI.EndChangeCheck())
     {
         InternalUtilities.SetDirty(target);
     }
 }
        private string GetItemPrefabName(UiLayoutPreset preset)
        {
            if (preset == null || string.IsNullOrEmpty(preset.PrefabPath))
            {
                return(string.Empty);
            }

            string[] levels = preset.PrefabPath.Split('/');

            return(levels[levels.Length - 1]);
        }
        // Render item element prefab field
        private void RenderListItemPrefab(List <UiLayoutPreset> list, UiLayoutPreset item, ItemType type)
        {
            GameObject      prefabOriginal = Resources.Load <GameObject>(item.PrefabPath);
            UiLayoutElement prefab         = prefabOriginal != null?prefabOriginal.GetComponent <UiLayoutElement>() : null;

            // Screen property
            EditorGUI.BeginChangeCheck();
            switch (type)
            {
            case ItemType.Popup:
                prefab = (UiLayoutElementPopup)EditorGUILayout.ObjectField("Prefab", prefab, typeof(UiLayoutElementPopup), allowSceneObjects: false);
                break;

            case ItemType.Panel:
                prefab = (UiLayoutElementPanel)EditorGUILayout.ObjectField("Prefab", prefab, typeof(UiLayoutElementPanel), allowSceneObjects: false);
                break;

            case ItemType.Screen:
                prefab = (UiLayoutElementScreen)EditorGUILayout.ObjectField("Prefab", prefab, typeof(UiLayoutElementScreen), allowSceneObjects: false);
                break;
            }

            if (EditorGUI.EndChangeCheck())
            {
                InternalUtilities.SetDirty(target);

                if (prefab != null)
                {
                    Match match = Regex.Match
                                  (
                        AssetDatabase.GetAssetPath(prefab.gameObject),
                        @"Resources/([A-Za-z0-9\-\/.]*).prefab",
                        RegexOptions.IgnoreCase
                                  );

                    item.PrefabPath = match.Success ? match.Groups[1].Value : string.Empty;

                    UiLayoutSettings.Signal signalShow = InternalUtilities.AddSignal("Ui." + GetItemPrefabName(item) + ".Show");
                    UiLayoutSettings.Signal signalHide = InternalUtilities.AddSignal("Ui." + GetItemPrefabName(item) + ".Hide");

                    item.SignalsShow = item.SignalsShow.Push(signalShow.Id);
                    item.SignalsHide = item.SignalsHide.Push(signalHide.Id);
                }
                else
                {
                    item.PrefabPath = string.Empty;
                    //item.SignalShow = string.Empty;
                    //item.SignalHide = string.Empty;
                }
            }
        }
        // Render item element foldout
        private UiLayoutPreset RenderListItemFoldOut(UiLayoutPreset item, UiLayoutPreset listItemSelected, ItemType type)
        {
            bool foldout = item == listItemSelected;

            string name = "Undefined";

            if (string.IsNullOrEmpty(item.PrefabPath))
            {
                switch (type)
                {
                case ItemType.Popup:
                    name = "Undefined popup preset";
                    break;

                case ItemType.Screen:
                    name = "Undefined screen preset";
                    break;

                case ItemType.Panel:
                    name = "Undefined panel preset";
                    break;
                }
            }
            else
            {
                switch (type)
                {
                case ItemType.Popup:
                    name = GetItemPrefabName(item);
                    break;

                case ItemType.Screen:
                case ItemType.Panel:
                    name = GetItemPrefabName(item) + (item.ActiveByDefault ? " (active by default)" : string.Empty);
                    break;
                }
            }

            EditorGUI.BeginChangeCheck();

            foldout = EditorGUILayout.Foldout(foldout, name, true);

            if (EditorGUI.EndChangeCheck())
            {
                InternalUtilities.SetDirty(target);

                listItemSelected = foldout ? item : null;
            }

            return(listItemSelected);
        }
        private void OnItemSetActiveByDefault(List <UiLayoutPreset> list, UiLayoutPreset item, bool value)
        {
            UiLayoutSettings layout = target as UiLayoutSettings;

            for (int i = 0; i < list.Count; i++)
            {
                if (list[i] != item)
                {
                    list[i].ActiveByDefault = false;
                }
            }

            item.ActiveByDefault = value;
        }
        private UiLayoutPreset RenderListItem(List <UiLayoutPreset> list, UiLayoutPreset item, int index, UiLayoutPreset listItemSelected, ItemType type)
        {
            GUIStyle style = new GUIStyle();

            style.padding.left = 15;

            GUILayout.BeginVertical(new GUIStyle(GUI.skin.GetStyle("HelpBox")));
            GUILayout.BeginVertical(style);

            // Foldout with item name
            listItemSelected = RenderListItemFoldOut(item, listItemSelected, type);

            // Render if is selected (foldouted)
            if (item == listItemSelected)
            {
                if (string.IsNullOrEmpty(item.PrefabPath))
                {
                    GUILayout.Label("Drag and drop prefab to setup this preset");
                }
                else
                {
                    GUILayout.Label(item.PrefabPath);
                }

                EditorGUILayout.Space();

                // Screen property
                RenderListItemPrefab(list, item, type);

                // Container property
                RenderListItemContainer(list, item, type);

                // Signals
                RenderListItemSignals(list, item, type);

                // Active by default
                RenderListItemActiveByDefault(list, item, type);
            }

            GUILayout.EndVertical();
            GUILayout.EndVertical();

            return(listItemSelected);
        }
        private UiLayoutPreset RenderList(List <UiLayoutPreset> list, UiLayoutPreset listItemSelected, ItemType type)
        {
            UiLayoutSettings layoutSettings = target as UiLayoutSettings;

            GUILayout.BeginVertical(new GUIStyle(GUI.skin.GetStyle("HelpBox")));

            if (list.Count == 0)
            {
                switch (type)
                {
                case ItemType.Screen:
                    EditorGUILayout.HelpBox("\nScreens is a basic layout elements like Main Menu, Choosing of level, Settings, etc. Only one slide can be active at the same time so if new slide shown then the old one will be automatically hidden. \n", MessageType.Info);
                    break;

                case ItemType.Panel:
                    EditorGUILayout.HelpBox("\nPanels is an additional layout elements like header, footer, etc. Panels can be shown and hided separatelly at any time. \n", MessageType.Info);
                    break;

                case ItemType.Popup:
                    EditorGUILayout.HelpBox("\nPopups is a overlaing layout elements like alerts, confirms and etc. Unlimited amount of same popups can be shown at the same time. After popup is hidden it's instance will be destroyed. \n", MessageType.Info);
                    break;
                }
            }

            // Items
            for (int i = 0; i < list.Count; i++)
            {
                listItemSelected = RenderListItem(list, list[i], i, listItemSelected, type);
            }

            // Buttons
            GUIStyle buttonsStyle = new GUIStyle();

            buttonsStyle.margin.left = -5;

            GUIStyle buttonStyle = new GUIStyle(GUI.skin.GetStyle("HelpBox"));

            buttonStyle.alignment    = TextAnchor.MiddleCenter;
            buttonStyle.stretchWidth = false;
            buttonStyle.fixedWidth   = 100;
            buttonStyle.fixedHeight  = 26;

            GUILayout.BeginHorizontal(buttonsStyle);

            EditorGUI.BeginChangeCheck();
            GUILayout.Button("ADD", buttonStyle);

            if (EditorGUI.EndChangeCheck())
            {
                InternalUtilities.SetDirty(target);

                UiLayoutPreset itemNew = new UiLayoutPreset();

                itemNew.Container = layoutSettings.DefaultContainer;

                list.Add(itemNew);
                listItemSelected = itemNew;
            }

            if (listItemSelected != null)
            {
                EditorGUI.BeginChangeCheck();
                GUILayout.Button("REMOVE", buttonStyle);
                if (EditorGUI.EndChangeCheck())
                {
                    InternalUtilities.SetDirty(target);

                    list.Remove(listItemSelected);
                    listItemSelected = null;
                }
            }

            GUILayout.EndHorizontal();
            GUILayout.EndVertical();
            return(listItemSelected);
        }