public static void RemoveElementFromSelectionInAsset(BuilderDocument document, VisualElement ve)
        {
            if (BuilderSharedStyles.IsSelectorsContainerElement(ve))
            {
                document.mainStyleSheet.RemoveSelector(
                    BuilderConstants.SelectedStyleSheetSelectorName,
                    BuilderConstants.ChangeSelectionUndoMessage);
            }
            else if (BuilderSharedStyles.IsSelectorElement(ve))
            {
                var scs = ve.GetStyleComplexSelector();
                document.mainStyleSheet.RemoveProperty(
                    scs,
                    BuilderConstants.SelectedStyleRulePropertyName,
                    BuilderConstants.ChangeSelectionUndoMessage);
            }
            else if (BuilderSharedStyles.IsDocumentElement(ve))
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vta             = ve.GetVisualTreeAsset();
                var selectedElement = vta.FindElementByType(BuilderConstants.SelectedVisualTreeAssetSpecialElementTypeName);
                vta.RemoveElement(selectedElement);
            }
            else if (ve.GetVisualElementAsset() != null)
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vea = ve.GetVisualElementAsset();
                vea.Deselect();
            }
        }
        public static void ReparentElementInAsset(
            BuilderDocument document, VisualElement veToReparent, VisualElement newParent, int index = -1, bool undo = true)
        {
            var veaToReparent = veToReparent.GetVisualElementAsset();

            if (veaToReparent == null)
            {
                return;
            }

            if (undo)
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ReparentUIElementUndoMessage);
            }

            VisualElementAsset veaNewParent = null;

            if (newParent != null)
            {
                veaNewParent = newParent.GetVisualElementAsset();
            }

#if !UNITY_2019_4
            if (veaNewParent == null)
            {
                veaNewParent = document.visualTreeAsset.GetRootUXMLElement(); // UXML Root Element
            }
#endif

            document.visualTreeAsset.ReparentElement(veaToReparent, veaNewParent, index);
        }
        public static VisualElementAsset AddElementToAsset(
            BuilderDocument document, VisualElement ve, int index = -1)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.CreateUIElementUndoMessage);

            var veParent = ve.parent;
            VisualElementAsset veaParent = null;

            if (veParent != null)
            {
                veaParent = veParent.GetVisualElementAsset();
            }

#if UNITY_2020_1_OR_NEWER
            if (veaParent == null)
            {
                veaParent = document.visualTreeAsset.GetRootUXMLElement(); // UXML Root Element
            }
#endif

            var vea = document.visualTreeAsset.AddElement(veaParent, ve);

            if (index >= 0)
            {
                document.visualTreeAsset.ReparentElement(vea, veaParent, index);
            }

            return(vea);
        }
        public static void AddElementToSelectionInAsset(BuilderDocument document, VisualElement ve)
        {
            if (BuilderSharedStyles.IsStyleSheetElement(ve))
            {
                var styleSheet = ve.GetStyleSheet();
                styleSheet.AddSelector(
                    BuilderConstants.SelectedStyleSheetSelectorName,
                    BuilderConstants.ChangeSelectionUndoMessage);
            }
            else if (BuilderSharedStyles.IsSelectorElement(ve))
            {
                var styleSheet = ve.GetClosestStyleSheet();
                var scs        = ve.GetStyleComplexSelector();
                AddStyleComplexSelectorToSelection(styleSheet, scs);
            }
            else if (BuilderSharedStyles.IsDocumentElement(ve))
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vta = ve.GetVisualTreeAsset();
                vta.AddElement(null, BuilderConstants.SelectedVisualTreeAssetSpecialElementTypeName);
            }
            else if (ve.GetVisualElementAsset() != null)
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vea = ve.GetVisualElementAsset();
                vea.Select();
            }
        }
        public static VisualElementAsset AddElementToAsset(
            BuilderDocument document, VisualElement ve, int index = -1)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.CreateUIElementUndoMessage);

            var veParent = ve.parent;
            VisualElementAsset veaParent = null;

            /* If the current parent element is linked to a VisualTreeAsset, it could mean
             * that our parent is the TemplateContainer belonging to our parent document and the
             * current open document is a sub-document opened in-place. In such a case, we don't
             * want to use our parent's VisualElementAsset, as that belongs to our parent document.
             * So instead, we just use no parent, indicating that we are adding this new element
             * to the root of our document.*/
            if (veParent != null && veParent.GetVisualTreeAsset() != document.visualTreeAsset)
            {
                veaParent = veParent.GetVisualElementAsset();
            }

            if (veaParent == null)
            {
                veaParent = document.visualTreeAsset.GetRootUXMLElement(); // UXML Root Element
            }
            var vea = document.visualTreeAsset.AddElement(veaParent, ve);

            if (index >= 0)
            {
                document.visualTreeAsset.ReparentElement(vea, veaParent, index);
            }

            return(vea);
        }
        public static VisualElementAsset AddElementToAsset(
            BuilderDocument document, VisualElement ve,
            Func <VisualTreeAsset, VisualElementAsset, VisualElementAsset> makeVisualElementAsset,
            int index = -1)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.CreateUIElementUndoMessage);

            var veParent  = ve.parent;
            var veaParent = veParent == null ? null : veParent.GetVisualElementAsset();

#if UNITY_2020_1_OR_NEWER
            if (veaParent == null)
            {
                veaParent = document.visualTreeAsset.GetRootUXMLElement(); // UXML Root Element
            }
#endif

            var vea = makeVisualElementAsset(document.visualTreeAsset, veaParent);
            ve.SetProperty(BuilderConstants.ElementLinkedVisualElementAssetVEPropertyName, vea);

            if (index >= 0)
            {
                document.visualTreeAsset.ReparentElement(vea, veaParent, index);
            }

            return(vea);
        }
        public static void TransferAssetToAsset(
            BuilderDocument document, VisualElementAsset parent, VisualTreeAsset otherVta)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.CreateUIElementUndoMessage);

            document.visualTreeAsset.Swallow(parent, otherVta);
        }
        public static void TransferAssetToAsset(
            BuilderDocument document, StyleSheet styleSheet, StyleSheet otherStyleSheet)
        {
            Undo.RegisterCompleteObjectUndo(
                styleSheet, BuilderConstants.AddNewSelectorUndoMessage);

            styleSheet.Swallow(otherStyleSheet);
        }
        public static void RemoveStyleSheetFromAsset(
            BuilderDocument document, int ussIndex)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Remove StyleSheet from UXML");

            document.RemoveStyleSheetFromDocument(ussIndex);
        }
        public static void RemoveStyleClassFromElementInAsset(BuilderDocument document, VisualElement ve, string className)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.RemoveStyleClassUndoMessage);

            var vea = ve.GetVisualElementAsset();

            vea.RemoveStyleClass(className);
        }
        public static void RemoveStyleSheetsFromAsset(
            BuilderDocument document, int[] indexes)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Remove StyleSheets from UXML");

            foreach (var index in indexes)
            {
                document.RemoveStyleSheetFromDocument(index);
            }
        }
        public static void AddStyleComplexSelectorToSelection(BuilderDocument document, StyleComplexSelector scs)
        {
            var selectionProp = document.mainStyleSheet.AddProperty(
                scs,
                BuilderConstants.SelectedStyleRulePropertyName,
                BuilderConstants.ChangeSelectionUndoMessage);

            // Need to add at least one dummy value because lots of code will die
            // if it encounters a style property with no values.
            document.mainStyleSheet.AddValue(
                selectionProp, 42.0f, BuilderConstants.ChangeSelectionUndoMessage);
        }
        internal static bool IsAssetUsedInDocument(BuilderDocument document, string assetPath)
        {
            // Check current document.
            var isAssetUsedInDocument = assetPath.Equals(document.uxmlPath) || document.ussPaths.Contains(assetPath);

            if (!isAssetUsedInDocument)
            {
                // Check uxml and uss paths in document dependencies.
                isAssetUsedInDocument = IsAssetUsedInDependencies(document.visualTreeAsset, assetPath);
            }

            return(isAssetUsedInDocument);
        }
        public static bool IsPartOfActiveVisualTreeAsset(this VisualElement element, BuilderDocument builderDocument)
        {
            var isSubDocument = builderDocument != null && builderDocument.activeOpenUXMLFile.isChildSubDocument;
            var elementVTA    = element.GetVisualTreeAsset();
            var activeVTA     = builderDocument == null ? elementVTA : builderDocument.activeOpenUXMLFile.visualTreeAsset;

            var belongsToActiveVisualTreeAsset = (VisualTreeAsset)element.GetProperty(BuilderConstants.ElementLinkedBelongingVisualTreeAssetVEPropertyName) == builderDocument?.visualTreeAsset;
            var hasAssetLink = element.GetVisualElementAsset() != null && belongsToActiveVisualTreeAsset;
            var hasVTALink   = elementVTA != null && elementVTA == activeVTA && !(element is TemplateContainer);

            var isDocumentRootElement = !isSubDocument && BuilderSharedStyles.IsDocumentElement(element);

            return(hasAssetLink || hasVTALink || isDocumentRootElement);
        }
        public static void DeleteElementFromAsset(BuilderDocument document, VisualElement ve)
        {
            var vea = ve.GetVisualElementAsset();

            if (vea == null)
            {
                return;
            }

            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, BuilderConstants.DeleteUIElementUndoMessage);

            document.visualTreeAsset.RemoveElement(vea);
        }
        public static void AddStyleSheetToAsset(
            BuilderDocument document, string ussPath)
        {
            var styleSheet = AssetDatabase.LoadAssetAtPath <StyleSheet>(ussPath);

            if (styleSheet == null)
            {
                BuilderDialogsUtility.DisplayDialog("Invalid Asset Type", @"Asset at path {ussPath} is not a StyleSheet.");
                return;
            }

            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Add StyleSheet to UXML");

            document.AddStyleSheetToDocument(styleSheet, ussPath);
        }
        public static void DeleteElementFromAsset(BuilderDocument document, VisualElement ve, bool registerUndo = true)
        {
            var vea = ve.GetVisualElementAsset();

            if (vea == null)
            {
                return;
            }

            if (registerUndo)
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.DeleteUIElementUndoMessage);
            }

            foreach (var child in ve.Children())
            {
                DeleteElementFromAsset(document, child, false);
            }

            document.visualTreeAsset.RemoveElement(vea);
        }
        public static void ReorderStyleSheetsInAsset(
            BuilderDocument document, VisualElement styleSheetsContainerElement)
        {
            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Reorder StyleSheets in UXML");

            var reorderedUSSList = new List <StyleSheet>();

            foreach (var ussElement in styleSheetsContainerElement.Children())
            {
                reorderedUSSList.Add(ussElement.GetStyleSheet());
            }

            var openUXMLFile = document.activeOpenUXMLFile;

            openUXMLFile.openUSSFiles.Sort((left, right) =>
            {
                var leftOrder  = reorderedUSSList.IndexOf(left.styleSheet);
                var rightOrder = reorderedUSSList.IndexOf(right.styleSheet);
                return(leftOrder.CompareTo(rightOrder));
            });
        }
        public static bool AddStyleSheetToAsset(
            BuilderDocument document, string ussPath)
        {
            var styleSheet = BuilderPackageUtilities.LoadAssetAtPath <StyleSheet>(ussPath);

            string errorMessage = null;
            string errorTitle   = null;

            if (styleSheet == null)
            {
                if (ussPath.StartsWith("Packages/"))
                {
                    errorMessage = $"Asset at path {ussPath} is not a StyleSheet.\nNote, for assets inside Packages folder, the folder name for the package needs to match the actual official package name (ie. com.example instead of Example).";
                }
                else
                {
                    errorMessage = $"Asset at path {ussPath} is not a StyleSheet.";
                }
                errorTitle = "Invalid Asset Type";
            }
            else if (styleSheet.importedWithErrors)
            {
                errorMessage = string.Format(BuilderConstants.InvalidUSSDialogMessage, ussPath);
                errorTitle   = BuilderConstants.InvalidUSSDialogTitle;
            }

            if (errorMessage != null)
            {
                BuilderDialogsUtility.DisplayDialog(errorTitle, errorMessage, "Ok");
                Debug.LogError(errorMessage);
                return(false);
            }

            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Add StyleSheet to UXML");

            document.AddStyleSheetToDocument(styleSheet, ussPath);
            return(true);
        }
        public static void AddElementToSelectionInAsset(BuilderDocument document, VisualElement ve)
        {
            if (BuilderSharedStyles.IsSelectorsContainerElement(ve))
            {
                document.mainStyleSheet.AddSelector(
                    BuilderConstants.SelectedStyleSheetSelectorName,
                    BuilderConstants.ChangeSelectionUndoMessage);
            }
            else if (BuilderSharedStyles.IsSelectorElement(ve))
            {
                var scs           = ve.GetStyleComplexSelector();
                var selectionProp = document.mainStyleSheet.AddProperty(
                    scs,
                    BuilderConstants.SelectedStyleRulePropertyName,
                    BuilderConstants.ChangeSelectionUndoMessage);

                // Need to add at least one dummy value because lots of code will die
                // if it encounters a style property with no values.
                document.mainStyleSheet.AddValue(
                    selectionProp, 42.0f, BuilderConstants.ChangeSelectionUndoMessage);
            }
            else if (BuilderSharedStyles.IsDocumentElement(ve))
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vta = ve.GetVisualTreeAsset();
                vta.AddElement(null, BuilderConstants.SelectedVisualTreeAssetSpecialElementTypeName);
            }
            else if (ve.GetVisualElementAsset() != null)
            {
                Undo.RegisterCompleteObjectUndo(
                    document.visualTreeAsset, BuilderConstants.ChangeSelectionUndoMessage);

                var vea = ve.GetVisualElementAsset();
                vea.Select();
            }
        }
        public static void AddStyleSheetToAsset(
            BuilderDocument document, string ussPath)
        {
            var styleSheet = BuilderPackageUtilities.LoadAssetAtPath <StyleSheet>(ussPath);

            if (styleSheet == null)
            {
                if (ussPath.StartsWith("Packages/"))
                {
                    BuilderDialogsUtility.DisplayDialog("Invalid Asset Type", $"Asset at path {ussPath} is not a StyleSheet.\nNote, for assets inside Packages folder, the folder name for the package needs to match the actual official package name (ie. com.example instead of Example).");
                }
                else
                {
                    BuilderDialogsUtility.DisplayDialog("Invalid Asset Type", $"Asset at path {ussPath} is not a StyleSheet.");
                }
                return;
            }

            Undo.RegisterCompleteObjectUndo(
                document.visualTreeAsset, "Add StyleSheet to UXML");

            document.AddStyleSheetToDocument(styleSheet, ussPath);
        }
        public BuilderInspectorCanvas(BuilderInspector inspector)
        {
            m_Inspector       = inspector;
            m_Document        = inspector.document;
            m_CanvasInspector = m_Inspector.Q("canvas-inspector");

            var builderWindow = inspector.paneWindow as Builder;

            if (builderWindow == null)
            {
                return;
            }

            m_Canvas = builderWindow.canvas;

            m_CameraModeEnabled = false;

            // Size Fields
            m_CanvasWidth           = root.Q <IntegerField>("canvas-width");
            m_CanvasWidth.isDelayed = true;
            m_CanvasWidth.RegisterValueChangedCallback(OnWidthChange);
            m_CanvasHeight           = root.Q <IntegerField>("canvas-height");
            m_CanvasHeight.isDelayed = true;
            m_CanvasHeight.RegisterValueChangedCallback(OnHeightChange);
            m_Canvas.RegisterCallback <GeometryChangedEvent>(OnCanvasSizeChange);

            // Background Opacity
            m_OpacityField = root.Q <PercentSlider>("background-opacity-field");
            m_OpacityField.RegisterValueChangedCallback(OnBackgroundOpacityChange);

            // Setup Background Mode
            var backgroundModeType   = typeof(BuilderCanvasBackgroundMode);
            var backgroundModeValues = Enum.GetValues(backgroundModeType)
                                       .OfType <BuilderCanvasBackgroundMode>().Select((v) => v.ToString()).ToList();
            var backgroundModeNames = Enum.GetNames(backgroundModeType);

            m_BackgroundMode          = root.Q <ToggleButtonStrip>("background-mode-field");
            m_BackgroundMode.enumType = backgroundModeType;
            m_BackgroundMode.labels   = backgroundModeNames;
            m_BackgroundMode.choices  = backgroundModeValues;
            m_BackgroundMode.RegisterValueChangedCallback(OnBackgroundModeChange);

            // Color field.
            m_ColorField = root.Q <ColorField>("background-color-field");
            m_ColorField.RegisterValueChangedCallback(OnBackgroundColorChange);

            // Set Image field.
            m_ImageField            = root.Q <ObjectField>("background-image-field");
            m_ImageField.objectType = typeof(Texture2D);
            m_ImageField.RegisterValueChangedCallback(OnBackgroundImageChange);
            m_ImageScaleModeField          = root.Q <ToggleButtonStrip>("background-image-scale-mode-field");
            m_ImageScaleModeField.enumType = typeof(ScaleMode);
            var backgroundScaleModeValues = Enum.GetValues(typeof(ScaleMode))
                                            .OfType <ScaleMode>().Select((v) => BuilderNameUtilities.ConvertCamelToDash(v.ToString())).ToList();

            m_ImageScaleModeField.choices = backgroundScaleModeValues;
            m_ImageScaleModeField.RegisterValueChangedCallback(OnBackgroundImageScaleModeChange);
            m_FitCanvasToImageButton = root.Q <Button>("background-image-fit-canvas-button");
            m_FitCanvasToImageButton.clickable.clicked += FitCanvasToImage;

            // Set Camera field.
            m_CameraField            = root.Q <ObjectField>("background-camera-field");
            m_CameraField.objectType = typeof(Camera);
            m_CameraField.RegisterValueChangedCallback(OnBackgroundCameraChange);

            // Control Containers
            m_BackgroundColorModeControls  = root.Q("canvas-background-color-mode-controls");
            m_BackgroundImageModeControls  = root.Q("canvas-background-image-mode-controls");
            m_BackgroundCameraModeControls = root.Q("canvas-background-camera-mode-controls");

            EditorApplication.playModeStateChanged += PlayModeStateChange;
        }
        public BuilderInspectorCanvas(BuilderInspector inspector)
        {
            m_Inspector       = inspector;
            m_Document        = inspector.document;
            m_CanvasInspector = m_Inspector.Q(ContainerName);

            var builderWindow = inspector.paneWindow as Builder;

            if (builderWindow == null)
            {
                return;
            }

            m_Canvas = builderWindow.canvas;

            m_CameraModeEnabled = false;

            // Size Fields
            m_CanvasWidth = root.Q <IntegerField>("canvas-width");
            m_CanvasWidth.RegisterValueChangedCallback(OnWidthChange);
            m_CanvasHeight = root.Q <IntegerField>("canvas-height");
            m_CanvasHeight.RegisterValueChangedCallback(OnHeightChange);
            m_Canvas.RegisterCallback <GeometryChangedEvent>(OnCanvasSizeChange);

            // This allows user to temporarily type values below the minimum canvas size
            SetDelayOnSizeFieldsEnabled(true);

            // To update the canvas size as user mouse drags the width or height labels
            DisableDelayOnActiveLabelMouseDraggers();

            m_MatchGameViewToggle = root.Q <Toggle>("match-game-view");
            m_MatchGameViewToggle.RegisterValueChangedCallback(OnMatchGameViewModeChanged);
            m_MatchGameViewHelpBox = root.Q <HelpBox>("match-game-view-hint");

            // Background Opacity
            m_ColorOpacityField = root.Q <PercentSlider>("background-color-opacity-field");
            m_ColorOpacityField.RegisterValueChangedCallback(e =>
            {
                settings.ColorModeBackgroundOpacity = e.newValue;
                OnBackgroundOpacityChange(e.newValue);
            });

            m_ImageOpacityField = root.Q <PercentSlider>("background-image-opacity-field");
            m_ImageOpacityField.RegisterValueChangedCallback(e =>
            {
                settings.ImageModeCanvasBackgroundOpacity = e.newValue;
                OnBackgroundOpacityChange(e.newValue);
            });

            m_CameraOpacityField = root.Q <PercentSlider>("background-camera-opacity-field");
            m_CameraOpacityField.RegisterValueChangedCallback(e =>
            {
                settings.CameraModeCanvasBackgroundOpacity = e.newValue;
                OnBackgroundOpacityChange(e.newValue);
            });

            // Setup Background State
            m_BackgroundOptionsFoldout = root.Q <FoldoutWithCheckbox>("canvas-background-foldout");
            m_BackgroundOptionsFoldout.RegisterCheckboxValueChangedCallback(e =>
            {
                settings.EnableCanvasBackground = e.newValue;
                PostSettingsChange();
                ApplyBackgroundOptions();
            });

            // Setup Background Mode
            var backgroundModeType   = typeof(BuilderCanvasBackgroundMode);
            var backgroundModeValues = Enum.GetValues(backgroundModeType)
                                       .OfType <BuilderCanvasBackgroundMode>().Select((v) => v.ToString()).ToList();

            m_BackgroundMode          = root.Q <ToggleButtonStrip>("background-mode-field");
            m_BackgroundMode.enumType = backgroundModeType;
            m_BackgroundMode.choices  = backgroundModeValues;
            m_BackgroundMode.RegisterValueChangedCallback(OnBackgroundModeChange);

            // Color field.
            m_ColorField = root.Q <ColorField>("background-color-field");
            m_ColorField.RegisterValueChangedCallback(OnBackgroundColorChange);

            // Set Image field.
            m_ImageField            = root.Q <ObjectField>("background-image-field");
            m_ImageField.objectType = typeof(Texture2D);
            m_ImageField.RegisterValueChangedCallback(OnBackgroundImageChange);
            m_ImageScaleModeField          = root.Q <ToggleButtonStrip>("background-image-scale-mode-field");
            m_ImageScaleModeField.enumType = typeof(ScaleMode);
            var backgroundScaleModeValues = Enum.GetValues(typeof(ScaleMode))
                                            .OfType <ScaleMode>().Select((v) => BuilderNameUtilities.ConvertCamelToDash(v.ToString())).ToList();

            m_ImageScaleModeField.choices = backgroundScaleModeValues;
            m_ImageScaleModeField.RegisterValueChangedCallback(OnBackgroundImageScaleModeChange);
            m_FitCanvasToImageButton = root.Q <Button>("background-image-fit-canvas-button");
            m_FitCanvasToImageButton.clickable.clicked += FitCanvasToImage;

            // Set Camera field.
            m_CameraField            = root.Q <ObjectField>("background-camera-field");
            m_CameraField.objectType = typeof(Camera);
            m_CameraField.RegisterValueChangedCallback(OnBackgroundCameraChange);

#if !UNITY_2019_4
            SetupEditorExtensionsModeToggle();
#else
            RemoveDocumentSettings();
#endif

            // Control Containers
            m_BackgroundColorModeControls  = root.Q("canvas-background-color-mode-controls");
            m_BackgroundImageModeControls  = root.Q("canvas-background-image-mode-controls");
            m_BackgroundCameraModeControls = root.Q("canvas-background-camera-mode-controls");

            EditorApplication.playModeStateChanged += PlayModeStateChange;
        }