private void OnUndo()
        {
            settings = ((DynamicPanelsCanvas)target).Internal;

            selectedAnchoredPanel     = settings.InitialPanelsAnchored;
            selectedAnchoredPanelTabs = selectedAnchoredPanel.panel.tabs;
        }
Example #2
0
        private void OnEnable()
        {
            settings = ((DynamicPanelsCanvas)target).Internal;

            reorderableLists      = new List <ReorderableList>();
            selectedAnchoredPanel = settings.InitialPanelsAnchored;

            minimumFreeSpace         = serializedObject.FindProperty("minimumFreeSpace");
            panelResizableAreaLength = serializedObject.FindProperty("m_panelResizableAreaLength");
            canvasAnchorZoneLength   = serializedObject.FindProperty("m_canvasAnchorZoneLength");
            panelAnchorZoneLength    = serializedObject.FindProperty("m_panelAnchorZoneLength");

            Undo.undoRedoPerformed -= OnUndo;
            Undo.undoRedoPerformed += OnUndo;
        }
        private void OnEnable()
        {
            settings = ((DynamicPanelsCanvas)target).Internal;

            reorderableLists          = new List <ReorderableList>();
            selectedAnchoredPanel     = settings.InitialPanelsAnchored;
            selectedAnchoredPanelTabs = selectedAnchoredPanel.panel.tabs;

            leaveFreeSpace           = serializedObject.FindProperty("m_leaveFreeSpace");
            minimumFreeSpace         = serializedObject.FindProperty("minimumFreeSpace");
            panelResizableAreaLength = serializedObject.FindProperty("m_panelResizableAreaLength");
            canvasAnchorZoneLength   = serializedObject.FindProperty("m_canvasAnchorZoneLength");
            panelAnchorZoneLength    = serializedObject.FindProperty("m_panelAnchorZoneLength");

            showIDs = EditorPrefs.GetBool(SHOW_IDS_PREF, false);

            Undo.undoRedoPerformed -= OnUndo;
            Undo.undoRedoPerformed += OnUndo;
        }
        private bool RemoveAnchoredPanel(DynamicPanelsCanvas.AnchoredPanelProperties root, DynamicPanelsCanvas.AnchoredPanelProperties panel)
        {
            for (int i = 0; i < root.subPanels.Count; i++)
            {
                if (root.subPanels[i] == panel)
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Remove Panel");

                    DynamicPanelsCanvas.AnchoredPanelProperties replacementPanel = null;
                    if (panel.subPanels.Count > 0)
                    {
                        replacementPanel = panel.subPanels[panel.subPanels.Count - 1];
                        panel.subPanels.RemoveAt(panel.subPanels.Count - 1);

                        if (replacementPanel != null)
                        {
                            replacementPanel.anchorDirection = panel.anchorDirection;
                            replacementPanel.subPanels.InsertRange(0, panel.subPanels);
                        }
                    }

                    if (replacementPanel == null)
                    {
                        root.subPanels.RemoveAt(i);
                    }
                    else
                    {
                        root.subPanels[i] = replacementPanel;
                    }

                    justClickedAnchoredPanel = settings.InitialPanelsAnchored;
                    return(true);
                }
                else if (RemoveAnchoredPanel(root.subPanels[i], panel))
                {
                    return(true);
                }
            }

            return(false);
        }
        public override void OnInspectorGUI()
        {
            if (anchoredPanelGUIStyle == null)
            {
                anchoredPanelGUIStyle = new GUIStyle("box")
                {
                    alignment = TextAnchor.MiddleCenter,
                    clipping  = TextClipping.Clip
                };
            }

            if (justClickedAnchoredPanel != null && Event.current.type == EventType.Layout)
            {
                selectedAnchoredPanel     = justClickedAnchoredPanel;
                selectedAnchoredPanelTabs = selectedAnchoredPanel.panel.tabs;

                justClickedAnchoredPanel = null;
            }

            serializedObject.Update();
            reorderableListIndex = 0;

            bool multiObjectEditing = targets.Length > 1;
            bool guiEnabled         = !EditorApplication.isPlaying || AssetDatabase.Contains(((DynamicPanelsCanvas)serializedObject.targetObject).gameObject);

            GUI.enabled = guiEnabled;
            GUILayout.BeginVertical();

            EditorGUILayout.LabelField("= Properties =", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(leaveFreeSpace);
            EditorGUI.indentLevel++;
            GUI.enabled = guiEnabled && leaveFreeSpace.boolValue;
            EditorGUILayout.PropertyField(minimumFreeSpace);
            EditorGUILayout.PropertyField(freeSpaceTargetTransform);
            GUI.enabled = guiEnabled;
            EditorGUI.indentLevel--;
            EditorGUILayout.PropertyField(preventDetachingLastDockedPanel);
            EditorGUILayout.PropertyField(panelResizableAreaLength);
            EditorGUILayout.PropertyField(canvasAnchorZoneLength);
            EditorGUILayout.PropertyField(panelAnchorZoneLength);

            GUILayout.Space(10f);

            EditorGUILayout.LabelField("= Free Panels =", EditorStyles.boldLabel);
            if (multiObjectEditing)
            {
                GUILayout.Label("Multi-object editing not supported");
            }
            else if (!guiEnabled)
            {
                GUILayout.Label("Can't edit in Play mode");
            }
            else
            {
                List <DynamicPanelsCanvas.PanelProperties> initialPanelsUnanchored = settings.InitialPanelsUnanchored;
                int selectedReorderableListIndex = -1;
                for (int i = 0; i < initialPanelsUnanchored.Count; i++)
                {
                    if (DrawReorderableListFor(initialPanelsUnanchored[i]))
                    {
                        selectedReorderableListIndex = i;
                    }

                    if (i < initialPanelsUnanchored.Count - 1)
                    {
                        // Draw a horizontal line to separate the panels
                        GUILayout.Space(5f);
                        GUILayout.Box(GUIContent.none, GUILayout.ExpandWidth(true), GUILayout.Height(2f));
                    }

                    GUILayout.Space(5f);
                }

                GUILayout.BeginHorizontal();

                if (GUILayout.Button("Add New", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Add Free Panel");

                    initialPanelsUnanchored.Add(new DynamicPanelsCanvas.PanelProperties());
                }

                if (selectedReorderableListIndex < 0)
                {
                    GUI.enabled = false;
                }

                if (GUILayout.Button("Remove Selected", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Remove Free Panel");

                    initialPanelsUnanchored.RemoveAt(selectedReorderableListIndex);
                }

                GUI.enabled = guiEnabled;

                GUILayout.EndHorizontal();
            }

            GUILayout.Space(13f);

            EditorGUILayout.LabelField("= Docked Panels =", EditorStyles.boldLabel);
            if (multiObjectEditing)
            {
                GUILayout.Label("Multi-object editing not supported");
            }
            else if (!guiEnabled)
            {
                GUILayout.Label("Can't edit in Play mode");
            }
            else
            {
                DynamicPanelsCanvas.AnchoredPanelProperties initialPanelsAnchored = settings.InitialPanelsAnchored;

                Rect previewRect = EditorGUILayout.GetControlRect(false, ANCHORED_PANELS_PREVIEW_HEIGHT);
                DrawAnchoredPanelsPreview(previewRect, initialPanelsAnchored);

                if (selectedAnchoredPanel != null)
                {
                    GUILayout.BeginVertical(EditorStyles.helpBox);
                    GUILayout.Space(5f);
                    EditorGUILayout.LabelField("Selected panel:", EditorStyles.boldLabel);

                    if (selectedAnchoredPanelTabs != settings.InitialPanelsAnchored.panel.tabs)
                    {
                        string initialSizeLabel = selectedAnchoredPanel.initialSize == Vector2.zero ? "Initial Size (not set):" : "Initial Size:";

                        EditorGUI.BeginChangeCheck();
                        Vector2 panelInitialSize = EditorGUILayout.Vector2Field(initialSizeLabel, selectedAnchoredPanel.initialSize);
                        if (EditorGUI.EndChangeCheck())
                        {
                            Undo.RecordObject((DynamicPanelsCanvas)target, "Change Initial Size");
                            selectedAnchoredPanel.initialSize = panelInitialSize;
                        }

                        DrawReorderableListFor(selectedAnchoredPanel.panel);
                    }
                    else
                    {
                        GUILayout.Label("- nothing -");
                    }

                    Direction direction = ShowDirectionButtons("Dock new panel inside: ");
                    if (direction != Direction.None)
                    {
                        Undo.IncrementCurrentGroup();
                        Undo.RecordObject((DynamicPanelsCanvas)target, "Dock New Panel");

                        selectedAnchoredPanel.subPanels.Add(new DynamicPanelsCanvas.AnchoredPanelProperties()
                        {
                            anchorDirection = direction
                        });
                    }

                    if (selectedAnchoredPanelTabs != settings.InitialPanelsAnchored.panel.tabs)
                    {
                        GUILayout.Space(5f);
                        if (GUILayout.Button("Remove Selected", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                        {
                            RemoveAnchoredPanel(settings.InitialPanelsAnchored, selectedAnchoredPanel);
                        }
                    }

                    GUILayout.EndVertical();
                }

                GUILayout.Space(6f);

                Direction rootDirection = ShowDirectionButtons("Dock new panel to canvas: ");
                if (rootDirection != Direction.None)
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Dock New Panel");

                    settings.InitialPanelsAnchored.subPanels.Insert(0, new DynamicPanelsCanvas.AnchoredPanelProperties()
                    {
                        anchorDirection = rootDirection
                    });
                }
            }

            GUI.enabled = true;
            GUILayout.EndVertical();

            serializedObject.ApplyModifiedProperties();
        }
        private void DrawAnchoredPanelsPreview(Rect rect, DynamicPanelsCanvas.AnchoredPanelProperties props)
        {
            bool shouldDrawSelf = leaveFreeSpace.boolValue || props != settings.InitialPanelsAnchored || props.subPanels == null || props.subPanels.Count == 0;

            if (props.subPanels != null && props.subPanels.Count > 0)
            {
                int horizontal = 1, vertical = 1;
                for (int i = 0; i < props.subPanels.Count; i++)
                {
                    Direction anchorDirection = props.subPanels[i].anchorDirection;
                    if (anchorDirection == Direction.Left || anchorDirection == Direction.Right)
                    {
                        horizontal++;
                    }
                    else
                    {
                        vertical++;
                    }
                }

                if (!shouldDrawSelf)
                {
                    Direction anchorDirection = props.subPanels[props.subPanels.Count - 1].anchorDirection;
                    if (anchorDirection == Direction.Left || anchorDirection == Direction.Right)
                    {
                        if (horizontal > 1)
                        {
                            horizontal--;
                        }
                    }
                    else
                    {
                        if (vertical > 1)
                        {
                            vertical--;
                        }
                    }
                }

                float perWidth  = rect.width / horizontal;
                float perHeight = rect.height / vertical;
                for (int i = 0; i < props.subPanels.Count; i++)
                {
                    Rect      subRect         = new Rect(rect);
                    Direction anchorDirection = props.subPanels[i].anchorDirection;
                    if (anchorDirection == Direction.Left)
                    {
                        rect.x       += perWidth;
                        rect.width   -= perWidth;
                        subRect.width = perWidth;
                    }
                    else if (anchorDirection == Direction.Top)
                    {
                        rect.y        += perHeight;
                        rect.height   -= perHeight;
                        subRect.height = perHeight;
                    }
                    else if (anchorDirection == Direction.Right)
                    {
                        rect.width   -= perWidth;
                        subRect.width = perWidth;
                        subRect.x     = rect.xMax;
                    }
                    else
                    {
                        rect.height   -= perHeight;
                        subRect.height = perHeight;
                        subRect.y      = rect.yMax;
                    }

                    DrawAnchoredPanelsPreview(subRect, props.subPanels[i]);
                }
            }

            if (!shouldDrawSelf)
            {
                return;
            }

            string label;

            if (props == settings.InitialPanelsAnchored)
            {
                label = "Free space";
            }
            else
            {
                label = "Panel";

                List <DynamicPanelsCanvas.PanelTabProperties> tabs = props.panel.tabs;
                for (int i = 0; i < tabs.Count; i++)
                {
                    if (!string.IsNullOrEmpty(tabs[i].tabLabel))
                    {
                        label = tabs[i].tabLabel;
                        break;
                    }
                }

                if (tabs.Count == 1)
                {
                    label = string.Concat(label, "\n1 tab");
                }
                else
                {
                    label = string.Concat(label, "\n", tabs.Count.ToString(), " tabs");
                }
            }

            if (selectedAnchoredPanel == props)
            {
                Color guiColor = GUI.color;
                GUI.color = Color.cyan;
                GUI.Box(rect, label, anchoredPanelGUIStyle);
                GUI.color = guiColor;
            }
            else
            {
                GUI.Box(rect, label, anchoredPanelGUIStyle);
            }

            int controlID = GUIUtility.GetControlID(FocusType.Passive);

            Event ev = Event.current;

            switch (ev.GetTypeForControl(controlID))
            {
            case EventType.MouseDown:
                if (rect.Contains(ev.mousePosition) && ev.button == 0)
                {
                    GUIUtility.hotControl    = controlID;
                    justClickedAnchoredPanel = props;
                }

                break;

            case EventType.MouseDrag:
                if (GUIUtility.hotControl == controlID && props != settings.InitialPanelsAnchored)
                {
                    GUIUtility.hotControl = 0;

                    // Credit: https://forum.unity.com/threads/editor-draganddrop-bug-system-needs-to-be-initialized-by-unity.219342/#post-1464056
                    DragAndDrop.PrepareStartDrag();
                    DragAndDrop.objectReferences = new Object[] { null };
                    DragAndDrop.SetGenericData("props", props);
                    DragAndDrop.StartDrag("AnchoredPanelProperties");

                    ev.Use();
                }

                break;

            case EventType.MouseUp:
                if (GUIUtility.hotControl == controlID)
                {
                    GUIUtility.hotControl = 0;
                }

                break;

            case EventType.DragPerform:
            case EventType.DragUpdated:
                if (props != settings.InitialPanelsAnchored && rect.Contains(ev.mousePosition))
                {
                    DynamicPanelsCanvas.AnchoredPanelProperties drag = DragAndDrop.GetGenericData("props") as DynamicPanelsCanvas.AnchoredPanelProperties;
                    if (drag == null)
                    {
                        int      i;
                        Object[] draggedObjects = DragAndDrop.objectReferences;
                        for (i = 0; i < draggedObjects.Length; i++)
                        {
                            if (draggedObjects[i] is GameObject || draggedObjects[i] is Component)
                            {
                                break;
                            }
                        }

                        if (i == draggedObjects.Length)
                        {
                            break;
                        }
                    }

                    DragAndDrop.visualMode = DragAndDropVisualMode.Move;
                    if (ev.type == EventType.DragPerform)
                    {
                        DragAndDrop.AcceptDrag();

                        if (drag != null)
                        {
                            Undo.IncrementCurrentGroup();
                            Undo.RecordObject((DynamicPanelsCanvas)target, "Swap Tabs");

                            DynamicPanelsCanvas.PanelProperties temp = props.panel;
                            props.panel = drag.panel;
                            drag.panel  = temp;
                        }
                        else
                        {
                            Undo.IncrementCurrentGroup();
                            Undo.RecordObject((DynamicPanelsCanvas)target, "Add Tabs");

                            Object[] draggedObjects = DragAndDrop.objectReferences;
                            for (int i = 0; i < draggedObjects.Length; i++)
                            {
                                RectTransform transform;
                                if (draggedObjects[i] is GameObject)
                                {
                                    transform = ((GameObject)draggedObjects[i]).transform as RectTransform;
                                }
                                else
                                {
                                    transform = ((Component)draggedObjects[i]).transform as RectTransform;
                                }

                                if (transform != null)
                                {
                                    if (props.panel.tabs.Find((tab) => tab.content == transform) == null)
                                    {
                                        props.panel.tabs.Add(new DynamicPanelsCanvas.PanelTabProperties()
                                        {
                                            content = transform
                                        });
                                    }
                                }
                            }
                        }
                    }

                    ev.Use();
                }

                break;
            }

            if (ev.isMouse && GUIUtility.hotControl == controlID)
            {
                ev.Use();
            }
        }
Example #7
0
        public override void OnInspectorGUI()
        {
            if (anchoredPanelGUIStyle == null)
            {
                anchoredPanelGUIStyle = new GUIStyle("box")
                {
                    alignment = TextAnchor.MiddleCenter,
                    clipping  = TextClipping.Clip
                };
            }

            if (justClickedAnchoredPanel != null && Event.current.type == EventType.Layout)
            {
                selectedAnchoredPanel    = justClickedAnchoredPanel;
                justClickedAnchoredPanel = null;
            }

            serializedObject.Update();
            reorderableListIndex = 0;

            bool multiObjectEditing = targets.Length > 1;
            bool guiEnabled         = !EditorApplication.isPlaying || PrefabUtility.GetPrefabType(((DynamicPanelsCanvas)serializedObject.targetObject).gameObject) == PrefabType.Prefab;

            GUI.enabled = guiEnabled;
            GUILayout.BeginVertical();

            EditorGUILayout.LabelField("= Properties =", EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(minimumFreeSpace);
            EditorGUILayout.PropertyField(panelResizableAreaLength);
            EditorGUILayout.PropertyField(canvasAnchorZoneLength);
            EditorGUILayout.PropertyField(panelAnchorZoneLength);

            GUILayout.Space(10f);

            EditorGUILayout.LabelField("= Free Panels =", EditorStyles.boldLabel);
            if (multiObjectEditing)
            {
                GUILayout.Label("Multi-object editing not supported");
            }
            else if (!guiEnabled)
            {
                GUILayout.Label("Can't edit in Play mode");
            }
            else
            {
                List <DynamicPanelsCanvas.PanelProperties> initialPanelsUnanchored = ((DynamicPanelsCanvas)target).Internal.InitialPanelsUnanchored;
                int selectedReorderableListIndex = -1;
                for (int i = 0; i < initialPanelsUnanchored.Count; i++)
                {
                    if (DrawReorderableListFor(initialPanelsUnanchored[i]))
                    {
                        selectedReorderableListIndex = i;
                    }

                    GUILayout.Space(5f);
                }

                GUILayout.BeginHorizontal();

                if (GUILayout.Button("Add New", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Add Free Panel");

                    initialPanelsUnanchored.Add(new DynamicPanelsCanvas.PanelProperties());
                }

                if (selectedReorderableListIndex < 0)
                {
                    GUI.enabled = false;
                }

                if (GUILayout.Button("Remove Selected", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Remove Free Panel");

                    initialPanelsUnanchored.RemoveAt(selectedReorderableListIndex);
                }

                GUI.enabled = guiEnabled;

                GUILayout.EndHorizontal();
            }

            GUILayout.Space(13f);

            EditorGUILayout.LabelField("= Docked Panels =", EditorStyles.boldLabel);
            if (multiObjectEditing)
            {
                GUILayout.Label("Multi-object editing not supported");
            }
            else if (!guiEnabled)
            {
                GUILayout.Label("Can't edit in Play mode");
            }
            else
            {
                DynamicPanelsCanvas.AnchoredPanelProperties initialPanelsAnchored = ((DynamicPanelsCanvas)target).Internal.InitialPanelsAnchored;

                Rect previewRect = EditorGUILayout.GetControlRect(false, anchoredPanelsPreviewHeight);
                DrawAnchoredPanelsPreview(previewRect, initialPanelsAnchored);

                if (selectedAnchoredPanel != null)
                {
                    GUILayout.BeginVertical(EditorStyles.helpBox);
                    GUILayout.Space(5f);
                    EditorGUILayout.LabelField("Selected panel:", EditorStyles.boldLabel);

                    if (selectedAnchoredPanel != settings.InitialPanelsAnchored)
                    {
                        DrawReorderableListFor(selectedAnchoredPanel.panel);
                    }
                    else
                    {
                        GUILayout.Label("- nothing -");
                    }

                    Direction direction = ShowDirectionButtons("Dock new panel inside: ");
                    if (direction != Direction.None)
                    {
                        Undo.IncrementCurrentGroup();
                        Undo.RecordObject((DynamicPanelsCanvas)target, "Dock New Panel");

                        selectedAnchoredPanel.subPanels.Add(new DynamicPanelsCanvas.AnchoredPanelProperties()
                        {
                            anchorDirection = direction
                        });
                    }

                    if (selectedAnchoredPanel != settings.InitialPanelsAnchored)
                    {
                        GUILayout.Space(5f);
                        if (GUILayout.Button("Remove Selected", GUILayout.Height(1.35f * EditorGUIUtility.singleLineHeight)))
                        {
                            RemoveAnchoredPanel(settings.InitialPanelsAnchored, selectedAnchoredPanel);
                        }
                    }

                    GUILayout.EndVertical();
                }

                GUILayout.Space(6f);

                Direction rootDirection = ShowDirectionButtons("Dock new panel to canvas: ");
                if (rootDirection != Direction.None)
                {
                    Undo.IncrementCurrentGroup();
                    Undo.RecordObject((DynamicPanelsCanvas)target, "Dock New Panel");

                    settings.InitialPanelsAnchored.subPanels.Insert(0, new DynamicPanelsCanvas.AnchoredPanelProperties()
                    {
                        anchorDirection = rootDirection
                    });
                }
            }

            GUI.enabled = true;
            GUILayout.EndVertical();

            serializedObject.ApplyModifiedProperties();
        }