public BuilderExplorer(
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderHierarchyDragger hierarchyDragger,
            BuilderElementContextMenu contextMenuManipulator,
            VisualElement documentElementRoot,
            HighlightOverlayPainter highlightOverlayPainter,
            string toolbarUxmlPath)
        {
            m_Viewport            = viewport;
            m_DocumentElementRoot = documentElementRoot;
            m_DocumentElement     = viewport.documentElement;
            AddToClassList(s_UssClassName);

            m_ClassDragger           = classDragger;
            m_HierarchyDragger       = hierarchyDragger;
            m_ContextMenuManipulator = contextMenuManipulator;

            m_SelectionMadeExternally = false;

            m_Selection = selection;

            // TODO: Transfer to own USS.
            var sheet = EditorGUIUtility.Load(k_DefaultStyleSheetPath) as StyleSheet;

            styleSheets.Add(sheet);
            StyleSheet colorSheet;

            if (EditorGUIUtility.isProSkin)
            {
                colorSheet = EditorGUIUtility.Load(k_DefaultDarkStyleSheetPath) as StyleSheet;
            }
            else
            {
                colorSheet = EditorGUIUtility.Load(k_DefaultLightStyleSheetPath) as StyleSheet;
            }
            styleSheets.Add(colorSheet);

            // Query the UI
            if (!string.IsNullOrEmpty(toolbarUxmlPath))
            {
                var template = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(toolbarUxmlPath);
                template.CloneTree(this);
            }

            // Create the Hierarchy View.
            m_ElementHierarchyView = new ElementHierarchyView(
                m_DocumentElement,
                selection, classDragger, hierarchyDragger,
                contextMenuManipulator, ElementSelected, highlightOverlayPainter);
            m_ElementHierarchyView.style.flexGrow = 1;
            Add(m_ElementHierarchyView);

            // Make sure the Hierarchy View gets focus when the pane gets focused.
            primaryFocusable = m_ElementHierarchyView.Q <ListView>();

            UpdateHierarchyAndSelection(false);
            m_ShouldRebuildHierarchyOnStyleChange = true;
        }
        public override void CreateUI()
        {
            var root = rootVisualElement;

            // Create selection.
            m_Selection = new BuilderSelection(root, this);

            // Create viewport first.
            m_Viewport = new BuilderViewport(this, selection, null);
            selection.documentElement = m_Viewport.documentElement;

            // Create the rest of the panes.
            m_Toolbar = new BuilderToolbar(this, selection, m_Viewport, null, null, null, null);
            root.Add(m_Viewport);
            m_Viewport.toolbar.Add(m_Toolbar);

            // Init selection.
            selection.AssignNotifiers(new IBuilderSelectionNotifier[]
            {
                document,
                m_Viewport,
                m_Viewport.parentTracker,
                m_Viewport.resizer,
                m_Viewport.mover,
                m_Viewport.anchorer
            });

            // Command Handler
            commandHandler.RegisterPane(m_Viewport);
            commandHandler.RegisterToolbar(m_Toolbar);

            OnEnableAfterAllSerialization();
        }
        public BuilderDragger(
            BuilderPaneWindow paneWindow,
            VisualElement root, BuilderSelection selection,
            BuilderViewport viewport = null, BuilderParentTracker parentTracker = null)
        {
            m_PaneWindow         = paneWindow;
            m_Root               = root;
            this.viewport        = viewport;
            m_Canvas             = viewport?.documentRootElement;
            m_Selection          = selection;
            m_ParentTracker      = parentTracker;
            m_PlacementIndicator = viewport?.placementIndicator;
            if (m_PlacementIndicator != null)
            {
                m_PlacementIndicator.documentRootElement = m_Canvas;
            }

            activators = new List <ManipulatorActivationFilter>();
            activators.Add(new ManipulatorActivationFilter {
                button = MouseButton.LeftMouse
            });

            m_Active           = false;
            m_WeStartedTheDrag = false;

            m_DraggedElement = CreateDraggedElement();
            m_DraggedElement.AddToClassList(s_DraggerPreviewClassName);
            m_Root.Add(m_DraggedElement);
        }
Beispiel #4
0
 public BuilderViewportDragger(
     BuilderPaneWindow paneWindow,
     VisualElement root, BuilderSelection selection,
     BuilderViewport viewport = null, BuilderParentTracker parentTracker = null)
     : base(paneWindow, root, selection, viewport, parentTracker)
 {
 }
 public BuilderZoomer(BuilderViewport viewport)
 {
     m_Viewport = viewport;
     m_Viewport.Q("viewport").AddManipulator(this);
     activators.Add(new ManipulatorActivationFilter {
         button = MouseButton.RightMouse, modifiers = EventModifiers.Alt
     });
 }
Beispiel #6
0
        public BuilderExplorer(
            BuilderPaneWindow paneWindow,
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderExplorerDragger explorerDragger,
            BuilderElementContextMenu contextMenuManipulator,
            VisualElement documentElementRoot,
            bool includeDocumentElementRoot,
            HighlightOverlayPainter highlightOverlayPainter,
            string toolbarUxmlPath)
        {
            m_PaneWindow                 = paneWindow;
            m_Viewport                   = viewport;
            m_DocumentElementRoot        = documentElementRoot;
            m_IncludeDocumentElementRoot = includeDocumentElementRoot;
            m_DocumentElement            = viewport.documentElement;
            AddToClassList(s_UssClassName);

            m_ClassDragger           = classDragger;
            m_ExplorerDragger        = explorerDragger;
            m_ContextMenuManipulator = contextMenuManipulator;

            m_SelectionMadeExternally = false;

            m_Selection = selection;


            // Query the UI
            if (!string.IsNullOrEmpty(toolbarUxmlPath))
            {
                var template = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(toolbarUxmlPath);
                template.CloneTree(this);
            }

            // Create the Hierarchy View.
            m_ElementHierarchyView = new ElementHierarchyView(
                m_PaneWindow,
                m_DocumentElement,
                selection, classDragger, explorerDragger,
                contextMenuManipulator, ElementSelectionChanged, highlightOverlayPainter);
            m_ElementHierarchyView.style.flexGrow = 1;
            Add(m_ElementHierarchyView);

            // Enable horizontal scrolling.
#if UNITY_2020_2_OR_NEWER
            m_ElementHierarchyView.Q <TreeView>().horizontalScrollingEnabled = true;
#endif

            // Make sure the Hierarchy View gets focus when the pane gets focused.
            primaryFocusable = m_ElementHierarchyView.Q <ListView>();

            UpdateHierarchyAndSelection(false);
            m_ShouldRebuildHierarchyOnStyleChange = true;
        }
 public BuilderLibraryDragger(
     BuilderPaneWindow paneWindow,
     VisualElement root, BuilderSelection selection,
     BuilderViewport viewport, BuilderParentTracker parentTracker,
     VisualElement explorerContainer,
     BuilderTooltipPreview tooltipPreview)
     : base(paneWindow, root, selection, viewport, parentTracker)
 {
     builderHierarchyRoot = explorerContainer;
     m_TooltipPreview     = tooltipPreview;
 }
 public BuilderPanner(BuilderViewport viewport)
 {
     m_Viewport = viewport;
     m_Viewport.Q("viewport").AddManipulator(this);
     activators.Add(new ManipulatorActivationFilter {
         button = MouseButton.MiddleMouse
     });
     activators.Add(new ManipulatorActivationFilter {
         button = MouseButton.LeftMouse, modifiers = EventModifiers.Alt | EventModifiers.Control
     });
 }
        public static void CloseEditor()
        {
            if (s_Viewport == null)
            {
                return;
            }

            s_Viewport.textEditor.Q(TextField.textInputUssName).UnregisterCallback <FocusOutEvent>(OnFocusOutEvent);
            s_Viewport.textEditor.UnregisterCallback <ChangeEvent <string> >(OnTextChanged);
            s_Viewport.editorLayer.AddToClassList(BuilderConstants.HiddenStyleClassName);
            s_EditedTextElement.UnregisterCallback <GeometryChangedEvent>(OnTextElementGeometryChanged);
            s_Viewport            = null;
            s_EditedElement       = null;
            s_EditedTextAttribute = null;
        }
Beispiel #10
0
        public BuilderLibrary(
            BuilderPaneWindow paneWindow, BuilderViewport viewport,
            BuilderSelection selection, BuilderLibraryDragger dragger,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow      = paneWindow;
            m_DocumentElement = viewport.documentElement;
            m_Selection       = selection;
            m_Dragger         = dragger;
            m_TooltipPreview  = tooltipPreview;

            AddToClassList(s_UssClassName);

            BuilderAssetModificationProcessor.Register(this);

            RefreshTreeView();
        }
        public override void CreateUI()
        {
            var root = rootVisualElement;

            // Load assets.
            var saveDialogTemplate = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.UIBuilderPackagePath + "/BuilderSaveDialog.uxml");

            // Load template.
            saveDialogTemplate.CloneTree(root);

            // Fetch the save dialog.
            var dialog = root.Q <ModalPopup>("save-dialog");

            // Create selection.
            m_Selection = new BuilderSelection(root, this);

            // Create viewport first.
            m_Viewport = new BuilderViewport(this, selection, null);
            selection.documentElement = m_Viewport.documentElement;

            // Create the rest of the panes.
            m_Toolbar = new BuilderToolbar(this, selection, dialog, m_Viewport, null, null, null, null);
            root.Add(m_Viewport);
            m_Viewport.toolbar.Add(m_Toolbar);

            // Init selection.
            selection.AssignNotifiers(new IBuilderSelectionNotifier[]
            {
                document,
                m_Viewport,
                m_Viewport.parentTracker,
                m_Viewport.resizer,
                m_Viewport.mover,
                m_Viewport.anchorer
            });

            // Command Handler
            commandHandler.RegisterPane(m_Viewport);
            commandHandler.RegisterToolbar(m_Toolbar);

            dialog.BringToFront();

            OnEnableAfterAllSerialization();
        }
 public BuilderHierarchy(
     BuilderViewport viewport,
     BuilderSelection selection,
     BuilderClassDragger classDragger,
     BuilderHierarchyDragger hierarchyDragger,
     BuilderElementContextMenu contextMenuManipulator,
     HighlightOverlayPainter highlightOverlayPainter)
     : base(
         viewport,
         selection,
         classDragger,
         hierarchyDragger,
         contextMenuManipulator,
         viewport.documentElement,
         highlightOverlayPainter,
         null)
 {
     viewDataKey = "builder-hierarchy";
 }
        public BuilderLibrary(
            BuilderPaneWindow paneWindow, BuilderViewport viewport,
            BuilderSelection selection, BuilderLibraryDragger dragger,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow      = paneWindow;
            m_DocumentElement = viewport.documentElement;
            m_Selection       = selection;
            m_Dragger         = dragger;
            m_TooltipPreview  = tooltipPreview;

            viewDataKey = "unity-ui-builder-library";

            // Load styles.
            AddToClassList(k_UssClassName);
            styleSheets.Add(AssetDatabase.LoadAssetAtPath <StyleSheet>(BuilderConstants.LibraryUssPathNoExt + ".uss"));
            styleSheets.Add(EditorGUIUtility.isProSkin
                ? AssetDatabase.LoadAssetAtPath <StyleSheet>(BuilderConstants.LibraryUssPathNoExt + "Dark.uss")
                : AssetDatabase.LoadAssetAtPath <StyleSheet>(BuilderConstants.LibraryUssPathNoExt + "Light.uss"));

            var template = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.LibraryUssPathNoExt + ".uxml");

            template.CloneTree(this);

            m_EditorExtensionMode     = paneWindow.document.UXMLFileSettings.EditorExtensionMode;
            m_LibraryContentContainer = this.Q <VisualElement>(k_ContentContainerName);

            m_HeaderButtonStrip         = this.Q <ToggleButtonStrip>();
            m_HeaderButtonStrip.choices = Enum.GetNames(typeof(BuilderLibraryTab));
            m_HeaderButtonStrip.labels  = new List <string> {
                BuilderConstants.LibraryStandardControlsTabName, BuilderConstants.LibraryProjectTabName
            };
            m_HeaderButtonStrip.RegisterValueChangedCallback(e =>
            {
                m_ActiveTab = (BuilderLibraryTab)Enum.Parse(typeof(BuilderLibraryTab), e.newValue);
                SaveViewData();
                RefreshView();
            });

            AddFocusable(m_HeaderButtonStrip);
            BuilderLibraryContent.OnLibraryContentUpdated += RebuildView;
        }
        public BuilderHierarchy(
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderHierarchyDragger hierarchyDragger,
            BuilderElementContextMenu contextMenuManipulator,
            HighlightOverlayPainter highlightOverlayPainter)
            : base(
                viewport,
                selection,
                classDragger,
                hierarchyDragger,
                contextMenuManipulator,
                viewport.documentElement,
                highlightOverlayPainter,
                kToolbarPath)
        {
            viewDataKey = "builder-hierarchy";

            m_HierarchyTypeClassVisibilityMenu = this.Q <ToolbarMenu>("hierarchy-visibility-toolbar-menu");
            SetUpHierarchyVisibilityMenu();
        }
Beispiel #15
0
        public BuilderStyleSheets(
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderHierarchyDragger hierarchyDragger,
            BuilderExplorerContextMenu contextMenuManipulator,
            HighlightOverlayPainter highlightOverlayPainter,
            BuilderTooltipPreview tooltipPreview)
            : base(
                viewport,
                selection,
                classDragger,
                hierarchyDragger,
                contextMenuManipulator,
                viewport.styleSelectorElementContainer,
                highlightOverlayPainter,
                kToolbarPath)
        {
            m_TooltipPreview = tooltipPreview;
            if (m_TooltipPreview != null)
            {
                var helpTooltipTemplate  = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(kHelpTooltipPath);
                var helpTooltipContainer = helpTooltipTemplate.CloneTree();
                m_TooltipPreview.Add(helpTooltipContainer); // We are the only ones using it so just add the contents and be done.
            }

            viewDataKey = "builder-style-sheets";
            AddToClassList(BuilderConstants.ExplorerStyleSheetsPaneClassName);

            var parent = this.Q("new-selector-item");

            // Init text field.
            m_NewSelectorTextField = parent.Q <TextField>("new-selector-field");
            m_NewSelectorTextField.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
            m_NewSelectorTextInputField = m_NewSelectorTextField.Q("unity-text-input");
            m_NewSelectorTextInputField.RegisterCallback <KeyDownEvent>(OnEnter, TrickleDown.TrickleDown);

            m_NewSelectorTextInputField.RegisterCallback <FocusEvent>((evt) =>
            {
                var input = evt.target as VisualElement;
                var field = input.parent as TextField;
                m_FieldFocusedFromStandby = true;
                if (field.text == BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage || m_NewSelectorJustCreated)
                {
                    m_NewSelectorJustCreated = false;
                    field.value = BuilderConstants.UssSelectorClassNameSymbol;
                }

                ShowTooltip();
            });

            m_NewSelectorTextField.RegisterCallback <ChangeEvent <string> >((evt) =>
            {
                var field = evt.target as TextField;

                if (!string.IsNullOrEmpty(evt.newValue) && evt.newValue != BuilderConstants.UssSelectorClassNameSymbol)
                {
                    m_NewSelectorAddButton.SetEnabled(true);
                    m_PseudoStatesMenu.SetEnabled(true);
                }
                else
                {
                    m_NewSelectorAddButton.SetEnabled(false);
                    m_PseudoStatesMenu.SetEnabled(false);
                }

                if (!m_FieldFocusedFromStandby)
                {
                    return;
                }

                m_FieldFocusedFromStandby = false;

                // We don't want the '.' we just inserted in the FocusEvent to be highlighted,
                // which is the default behavior.
                field.SelectRange(1, 1);
            });

            m_NewSelectorTextInputField.RegisterCallback <BlurEvent>((evt) =>
            {
                var input = evt.target as VisualElement;
                var field = input.parent as TextField;
                if (m_NewSelectorJustCreated)
                {
                    field.schedule.Execute(PostEnterRefocus);
                    evt.PreventDefault();
                    evt.StopImmediatePropagation();
                    return;
                }

                if (string.IsNullOrEmpty(field.text) || field.text == BuilderConstants.UssSelectorClassNameSymbol)
                {
                    field.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
                    m_NewSelectorAddButton.SetEnabled(false);
                    m_PseudoStatesMenu.SetEnabled(false);
                }

                HideTooltip();
            });

            // Setup new selector button.
            m_NewSelectorAddButton = parent.Q <ToolbarButton>("add-new-selector-button");
            m_NewSelectorAddButton.clickable.clicked += OnAddPress;
            m_NewSelectorAddButton.SetEnabled(false);

            // Setup pseudo states menu.
            m_PseudoStatesMenu = parent.Q <ToolbarMenu>("add-pseudo-state-menu");
            m_PseudoStatesMenu.SetEnabled(false);
            SetUpPseudoStatesMenu();
        }
        public BuilderToolbar(
            BuilderPaneWindow paneWindow,
            BuilderSelection selection,
            BuilderViewport viewport,
            BuilderExplorer explorer,
            BuilderLibrary library,
            BuilderInspector inspector,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow     = paneWindow;
            m_Selection      = selection;
            m_Viewport       = viewport;
            m_Explorer       = explorer;
            m_Library        = library;
            m_Inspector      = inspector;
            m_TooltipPreview = tooltipPreview;

            var template = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(
                BuilderConstants.UIBuilderPackagePath + "/BuilderToolbar.uxml");

            template.CloneTree(this);

            m_ThemeManager                    = new ThemeStyleSheetManager(this);
            m_ThemeManager.selection          = m_Selection;
            m_ThemeManager.themeFilesChanged += UpdateCanvasThemeMenuStatus;

            // File Menu
            m_FileMenu = this.Q <ToolbarMenu>("file-menu");
            SetUpFileMenu();

            // Zoom Menu
            m_ZoomMenu = this.Q <ToolbarMenu>("zoom-menu");
            SetUpZoomMenu();

            // Fit canvas
            m_FitCanvasButton = this.Q <ToolbarButton>(FitCanvasButtonName);
            m_FitCanvasButton.clickable.clicked += () => m_Viewport.FitCanvas();

            // Preview Button
            var previewButton = this.Q <ToolbarToggle>(PreviewToggleName);

            previewButton.RegisterValueChangedCallback(TogglePreviewMode);

            m_Viewport.SetPreviewMode(false);

            m_CanvasThemeMenu = this.Q <ToolbarMenu>("canvas-theme-menu");

            InitCanvasTheme();

            SetViewportSubTitle();

            // Track unsaved changes state change.
            UpdateHasUnsavedChanges();

            m_SettingsMenu = this.Q <ToolbarMenu>("settings-menu");
            SetupSettingsMenu();

            // Breadcrumbs & BreadCrumbs Toolbar
            m_BreadcrumbsToolbar = this.Q <Toolbar>(BreadcrumbsToolbarName);
            m_Breadcrumbs        = this.Q <ToolbarBreadcrumbs>(BreadcrumbsName);
            SetToolbarBreadCrumbs();

            RegisterCallback <AttachToPanelEvent>(RegisterCallbacks);
        }
        public BuilderStyleSheets(
            BuilderPaneWindow paneWindow,
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderStyleSheetsDragger styleSheetsDragger,
            HighlightOverlayPainter highlightOverlayPainter,
            BuilderTooltipPreview tooltipPreview)
            : base(
                paneWindow,
                viewport,
                selection,
                classDragger,
                styleSheetsDragger,
                new BuilderStyleSheetsContextMenu(paneWindow, selection),
                viewport.styleSelectorElementContainer,
                false,
                highlightOverlayPainter,
                kToolbarPath)
        {
            m_TooltipPreview = tooltipPreview;
            if (m_TooltipPreview != null)
            {
                var helpTooltipTemplate  = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(kHelpTooltipPath);
                var helpTooltipContainer = helpTooltipTemplate.CloneTree();
                m_TooltipPreview.Add(helpTooltipContainer); // We are the only ones using it so just add the contents and be done.
            }

            viewDataKey = "builder-style-sheets";
            AddToClassList(BuilderConstants.ExplorerStyleSheetsPaneClassName);

            var parent = this.Q("new-selector-item");

            // Init text field.
            m_NewSelectorField     = parent.Q <BuilderNewSelectorField>("new-selector-field");
            m_NewSelectorTextField = m_NewSelectorField.textField;
            m_NewSelectorTextField.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
            m_NewSelectorTextInputField = m_NewSelectorTextField.Q("unity-text-input");
            m_NewSelectorTextInputField.RegisterCallback <KeyDownEvent>(OnEnter, TrickleDown.TrickleDown);
            UpdateNewSelectorFieldEnabledStateFromDocument();

            m_NewSelectorTextInputField.RegisterCallback <FocusEvent>((evt) =>
            {
                var input        = evt.target as VisualElement;
                var field        = GetTextFieldParent(input);
                m_FieldFocusStep = FieldFocusStep.FocusedFromStandby;
                if (field.text == BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage || m_ShouldRefocusSelectorFieldOnBlur)
                {
                    m_ShouldRefocusSelectorFieldOnBlur = false;
                    field.value = BuilderConstants.UssSelectorClassNameSymbol;
                }

                ShowTooltip();
            }, TrickleDown.TrickleDown);

            m_NewSelectorTextField.RegisterCallback <ChangeEvent <string> >((evt) =>
            {
                if (m_FieldFocusStep != FieldFocusStep.FocusedFromStandby)
                {
                    return;
                }

                m_FieldFocusStep = m_NewSelectorTextField.value == BuilderConstants.UssSelectorClassNameSymbol ? FieldFocusStep.NeedsSelectionOverride : FieldFocusStep.Idle;

                // We don't want the '.' we just inserted in the FocusEvent to be highlighted,
                // which is the default behavior. Same goes for when we add pseudo states with options menu.
                m_NewSelectorTextField.SelectRange(m_NewSelectorTextField.value.Length, m_NewSelectorTextField.value.Length);
            });

            // Since MouseDown captures the mouse, we need to RegisterCallback directly on the target in order to intercept the event.
            // This could be replaced by setting selectAllOnMouseUp to false.
            m_NewSelectorTextInputField.Q <TextElement>().RegisterCallback <MouseUpEvent>((evt) =>
            {
                // We want to prevent the default action on mouse up in KeyboardTextEditor, but only when
                // the field selection behaviour was changed by us.
                if (m_FieldFocusStep != FieldFocusStep.NeedsSelectionOverride)
                {
                    return;
                }

                m_FieldFocusStep = FieldFocusStep.Idle;

                // Reselect on the next execution, after the KeyboardTextEditor selects all.
                m_NewSelectorTextInputField.schedule.Execute(() =>
                {
                    m_NewSelectorTextField.SelectRange(m_NewSelectorTextField.value.Length, m_NewSelectorTextField.value.Length);
                });
            }, TrickleDown.TrickleDown);

            m_NewSelectorTextInputField.RegisterCallback <BlurEvent>((evt) =>
            {
                var input = evt.target as VisualElement;
                var field = GetTextFieldParent(input);
                if (m_ShouldRefocusSelectorFieldOnBlur)
                {
                    field.schedule.Execute(PostEnterRefocus);
                    evt.PreventDefault();
                    evt.StopImmediatePropagation();
                    return;
                }

                if (string.IsNullOrEmpty(field.text) || field.text == BuilderConstants.UssSelectorClassNameSymbol)
                {
                    field.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
                    m_PseudoStatesMenu.SetEnabled(false);
                }

                HideTooltip();
            }, TrickleDown.TrickleDown);

            // Setup New USS Menu.
            m_AddUSSMenu = parent.Q <ToolbarMenu>("add-uss-menu");
            SetUpAddUSSMenu();

            // Setup pseudo states menu.
            m_PseudoStatesMenu = m_NewSelectorField.pseudoStatesMenu;

            // Update sub title.
            UpdateSubtitleFromActiveUSS();

            // Init drag stylesheet root
            classDragger.builderStylesheetRoot       = container;
            styleSheetsDragger.builderStylesheetRoot = container;

            RegisterCallback <GeometryChangedEvent>(e => AdjustPosition());
        }
        public BuilderToolbar(
            BuilderPaneWindow paneWindow,
            BuilderSelection selection,
            BuilderViewport viewport,
            BuilderExplorer explorer,
            BuilderLibrary library,
            BuilderInspector inspector,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow     = paneWindow;
            m_Selection      = selection;
            m_Viewport       = viewport;
            m_Explorer       = explorer;
            m_Library        = library;
            m_Inspector      = inspector;
            m_TooltipPreview = tooltipPreview;

            var template = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(
                BuilderConstants.UIBuilderPackagePath + "/BuilderToolbar.uxml");

            template.CloneTree(this);

            m_ThemeManager                    = new ThemeStyleSheetManager(this);
            m_ThemeManager.selection          = m_Selection;
            m_ThemeManager.themeFilesChanged += UpdateCanvasThemeMenuStatus;

            // File Menu
            m_FileMenu = this.Q <ToolbarMenu>("file-menu");
            SetUpFileMenu();

            // Zoom Menu
            m_ZoomMenu = this.Q <ToolbarMenu>("zoom-menu");
            SetUpZoomMenu();

            // Fit canvas
            m_FitCanvasButton = this.Q <ToolbarButton>(FitCanvasButtonName);
            m_FitCanvasButton.clickable.clicked += () => m_Viewport.FitCanvas();

            // Preview Button
            var previewButton = this.Q <ToolbarToggle>(PreviewToggleName);

            previewButton.RegisterValueChangedCallback(TogglePreviewMode);

            m_Viewport.SetPreviewMode(false);

            m_CanvasThemeMenu = this.Q <ToolbarMenu>("canvas-theme-menu");
            SetUpCanvasThemeMenu();

            var currentTheme      = document.currentCanvasTheme;
            var currentThemeSheet = document.currentCanvasThemeStyleSheet;

            // If the canvas theme is the obsolete Runtime enum then search for the unity default runtime theme in the current project.
            // Otherwise, fallback to the current editor theme
            if (currentTheme == BuilderDocument.CanvasTheme.Runtime)
            {
                var defaultTssAsset = EditorGUIUtility.Load(ThemeRegistry.kUnityRuntimeThemePath) as ThemeStyleSheet;
                if (defaultTssAsset != null)
                {
                    currentTheme      = BuilderDocument.CanvasTheme.Custom;
                    currentThemeSheet = defaultTssAsset;
                }
                else
                {
                    currentTheme = BuilderDocument.CanvasTheme.Default;
                }
            }

            ChangeCanvasTheme(currentTheme, currentThemeSheet);
            UpdateCanvasThemeMenuStatus();
            SetViewportSubTitle();

            // Track unsaved changes state change.
            UpdateHasUnsavedChanges();

            m_SettingsMenu = this.Q <ToolbarMenu>("settings-menu");
            SetupSettingsMenu();

            // Breadcrumbs & BreadCrumbs Toolbar
            m_BreadcrumbsToolbar = this.Q <Toolbar>(BreadcrumbsToolbarName);
            m_Breadcrumbs        = this.Q <ToolbarBreadcrumbs>(BreadcrumbsName);
            SetToolbarBreadCrumbs();

            // Get Builder package version.
            var packageInfo = PackageInfo.FindForAssetPath("Packages/" + BuilderConstants.BuilderPackageName);

            if (packageInfo == null)
            {
                m_BuilderPackageVersion = null;
            }
            else
            {
                m_BuilderPackageVersion = packageInfo.version;
            }

            RegisterCallback <AttachToPanelEvent>(RegisterCallbacks);
        }
        public BuilderStyleSheets(
            BuilderPaneWindow paneWindow,
            BuilderViewport viewport,
            BuilderSelection selection,
            BuilderClassDragger classDragger,
            BuilderStyleSheetsDragger styleSheetsDragger,
            HighlightOverlayPainter highlightOverlayPainter,
            BuilderTooltipPreview tooltipPreview)
            : base(
                paneWindow,
                viewport,
                selection,
                classDragger,
                styleSheetsDragger,
                new BuilderStyleSheetsContextMenu(paneWindow, selection),
                viewport.styleSelectorElementContainer,
                false,
                highlightOverlayPainter,
                kToolbarPath)
        {
            m_TooltipPreview = tooltipPreview;
            if (m_TooltipPreview != null)
            {
                var helpTooltipTemplate  = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(kHelpTooltipPath);
                var helpTooltipContainer = helpTooltipTemplate.CloneTree();
                m_TooltipPreview.Add(helpTooltipContainer); // We are the only ones using it so just add the contents and be done.
            }

            viewDataKey = "builder-style-sheets";
            AddToClassList(BuilderConstants.ExplorerStyleSheetsPaneClassName);

            var parent = this.Q("new-selector-item");

            // Init text field.
            m_NewSelectorField     = parent.Q <BuilderNewSelectorField>("new-selector-field");
            m_NewSelectorTextField = m_NewSelectorField.textField;
            m_NewSelectorTextField.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
            m_NewSelectorTextInputField = m_NewSelectorTextField.Q("unity-text-input");
            m_NewSelectorTextInputField.RegisterCallback <KeyDownEvent>(OnEnter, TrickleDown.TrickleDown);
            UpdateNewSelectorFieldEnabledStateFromDocument();

            m_NewSelectorTextInputField.RegisterCallback <FocusEvent>((evt) =>
            {
                var input = evt.target as VisualElement;
                var field = input.parent as TextField;
                m_FieldFocusedFromStandby = true;
                if (field.text == BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage || m_ShouldRefocusSelectorFieldOnBlur)
                {
                    m_ShouldRefocusSelectorFieldOnBlur = false;
                    field.value = BuilderConstants.UssSelectorClassNameSymbol;
                }

                ShowTooltip();
            });

            m_NewSelectorTextField.RegisterCallback <ChangeEvent <string> >((evt) =>
            {
                var field = evt.target as TextField;

                if (!m_FieldFocusedFromStandby)
                {
                    return;
                }

                m_FieldFocusedFromStandby = false;

                // We don't want the '.' we just inserted in the FocusEvent to be highlighted,
                // which is the default behavior.
                field.SelectRange(1, 1);
            });

            m_NewSelectorTextInputField.RegisterCallback <BlurEvent>((evt) =>
            {
                var input = evt.target as VisualElement;
                var field = input.parent as TextField;
                if (m_ShouldRefocusSelectorFieldOnBlur)
                {
                    field.schedule.Execute(PostEnterRefocus);
                    evt.PreventDefault();
                    evt.StopImmediatePropagation();
                    return;
                }

                if (string.IsNullOrEmpty(field.text) || field.text == BuilderConstants.UssSelectorClassNameSymbol)
                {
                    field.SetValueWithoutNotify(BuilderConstants.ExplorerInExplorerNewClassSelectorInfoMessage);
                    m_PseudoStatesMenu.SetEnabled(false);
                }

                HideTooltip();
            });

            // Setup New USS Menu.
            m_AddUSSMenu = parent.Q <ToolbarMenu>("add-uss-menu");
            SetUpAddUSSMenu();

            // Setup pseudo states menu.
            m_PseudoStatesMenu = m_NewSelectorField.pseudoStatesMenu;

            // Update sub title.
            UpdateSubtitleFromActiveUSS();
        }
Beispiel #20
0
        public override void CreateUI()
        {
            var root = rootVisualElement;

            // Load assets.
            var builderTemplate    = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.UIBuilderPackagePath + "/Builder.uxml");
            var saveDialogTemplate = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.UIBuilderPackagePath + "/BuilderSaveDialog.uxml");

            // Load templates.
            builderTemplate.CloneTree(root);
            saveDialogTemplate.CloneTree(root);

            // Create overlay painter.
            m_HighlightOverlayPainter = new HighlightOverlayPainter();

            // Fetch the save dialog.
            var dialog = root.Q <ModalPopup>("save-dialog");

            // Fetch the tooltip previews.
            var styleSheetsPaneTooltipPreview = root.Q <BuilderTooltipPreview>("stylesheets-pane-tooltip-preview");
            var libraryTooltipPreview         = root.Q <BuilderTooltipPreview>("library-tooltip-preview");

            // Create selection.
            m_Selection = new BuilderSelection(root, this);

            // Create Element Context Menu Manipulator
            var contextMenuManipulator = new BuilderElementContextMenu(this, selection);

            // Create viewport first.
            m_Viewport = new BuilderViewport(this, selection, contextMenuManipulator);
            selection.documentElement = m_Viewport.documentElement;
            var overlayHelper = viewport.Q <OverlayPainterHelperElement>();

            overlayHelper.painter = m_HighlightOverlayPainter;

            // Create the rest of the panes.
            var classDragger     = new BuilderClassDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker);
            var hierarchyDragger = new BuilderHierarchyDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker);
            var styleSheetsPane  = new BuilderStyleSheets(m_Viewport, selection, classDragger, hierarchyDragger, contextMenuManipulator, m_HighlightOverlayPainter, styleSheetsPaneTooltipPreview);
            var hierarchy        = new BuilderHierarchy(m_Viewport, selection, classDragger, hierarchyDragger, contextMenuManipulator, m_HighlightOverlayPainter);
            var libraryDragger   = new BuilderLibraryDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker, hierarchy.container, libraryTooltipPreview);

            m_Library     = new BuilderLibrary(this, m_Viewport, selection, libraryDragger, libraryTooltipPreview);
            m_Inspector   = new BuilderInspector(this, selection);
            m_Toolbar     = new BuilderToolbar(this, selection, dialog, m_Viewport, hierarchy, m_Library, m_Inspector, libraryTooltipPreview);
            m_UxmlPreview = new BuilderUxmlPreview(this);
            m_UssPreview  = new BuilderUssPreview(this);
            root.Q("viewport").Add(m_Viewport);
            m_Viewport.toolbar.Add(m_Toolbar);
            root.Q("library").Add(m_Library);
            root.Q("style-sheets").Add(styleSheetsPane);
            root.Q("hierarchy").Add(hierarchy);
            root.Q("uxml-preview").Add(m_UxmlPreview);
            root.Q("uss-preview").Add(m_UssPreview);
            root.Q("inspector").Add(m_Inspector);

            // Init selection.
            selection.AssignNotifiers(new IBuilderSelectionNotifier[]
            {
                document,
                m_Viewport,
                styleSheetsPane,
                hierarchy,
                m_Inspector,
                m_UxmlPreview,
                m_UssPreview,
                m_Viewport.parentTracker,
                m_Viewport.resizer,
                m_Viewport.mover,
                m_Viewport.anchorer
            });

            // Command Handler
            commandHandler.RegisterPane(styleSheetsPane);
            commandHandler.RegisterPane(hierarchy);
            commandHandler.RegisterPane(m_Viewport);
            commandHandler.RegisterToolbar(m_Toolbar);

            OnEnableAfterAllSerialization();
        }
        public BuilderToolbar(
            BuilderPaneWindow paneWindow,
            BuilderSelection selection,
            BuilderViewport viewport,
            BuilderExplorer explorer,
            BuilderLibrary library,
            BuilderInspector inspector,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow     = paneWindow;
            m_Selection      = selection;
            m_Viewport       = viewport;
            m_Explorer       = explorer;
            m_Library        = library;
            m_Inspector      = inspector;
            m_TooltipPreview = tooltipPreview;

            var template = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(
                BuilderConstants.UIBuilderPackagePath + "/BuilderToolbar.uxml");

            template.CloneTree(this);

#if !UNITY_2019_4 && !UNITY_2020_1
            m_ThemeManager                    = new ThemeStyleSheetManager(this);
            m_ThemeManager.selection          = m_Selection;
            m_ThemeManager.themeFilesChanged += UpdateCanvasThemeMenuStatus;
#else
            m_ThemeManager = null;
#endif

            // File Menu
            m_FileMenu = this.Q <ToolbarMenu>("file-menu");
            SetUpFileMenu();

            // Zoom Menu
            m_ZoomMenu = this.Q <ToolbarMenu>("zoom-menu");
            SetUpZoomMenu();

            // Fit canvas
            m_FitCanvasButton = this.Q <ToolbarButton>(FitCanvasButtonName);
            m_FitCanvasButton.clickable.clicked += () => m_Viewport.FitCanvas();

            // Preview Button
            var previewButton = this.Q <ToolbarToggle>(PreviewToggleName);
            previewButton.RegisterValueChangedCallback(TogglePreviewMode);

            m_CanvasThemeMenu = this.Q <ToolbarMenu>("canvas-theme-menu");
            SetUpCanvasThemeMenu();
            ChangeCanvasTheme(document.currentCanvasTheme, document.currentCanvasThemeStyleSheet);
            UpdateCanvasThemeMenuStatus();
            SetViewportSubTitle();

            // Track unsaved changes state change.
            SetCanvasTitle();

            m_SettingsMenu = this.Q <ToolbarMenu>("settings-menu");
            SetupSettingsMenu();

            // Breadcrumbs & BreadCrumbs Toolbar
            m_BreadcrumbsToolbar = this.Q <Toolbar>(BreadcrumbsToolbarName);
            m_Breadcrumbs        = this.Q <ToolbarBreadcrumbs>(BreadcrumbsName);
            SetToolbarBreadCrumbs();

            // Get Builder package version.
            var packageInfo = PackageInfo.FindForAssetPath("Packages/" + BuilderConstants.BuilderPackageName);
            if (packageInfo == null)
            {
                m_BuilderPackageVersion = null;
            }
            else
            {
                m_BuilderPackageVersion = packageInfo.version;
            }

            RegisterCallback <AttachToPanelEvent>(RegisterCallbacks);
        }
        public static void OpenEditor(VisualElement element, Vector2 pos)
        {
            BuilderViewport viewport    = element.GetFirstAncestorOfType <BuilderViewport>();
            var             editorLayer = viewport.editorLayer;
            var             textEditor  = viewport.textEditor;

            GetAttributeToEdit(element, pos, out var textElement, out var attributeName);

            if (textElement == null || string.IsNullOrEmpty(attributeName))
            {
                return;
            }

            var attributeList = element.GetAttributeDescriptions();

            foreach (var attribute in attributeList)
            {
                if (attribute?.name != null && attribute.name.Equals(attributeName))
                {
                    s_EditedTextAttribute = attribute;
                    break;
                }
            }

            if (s_EditedTextAttribute == null)
            {
                return;
            }

            s_Viewport          = viewport;
            s_EditedElement     = element;
            s_EditedTextElement = textElement;

            var value = s_EditedElement.GetValueByReflection(s_EditedTextAttribute.name) as string;

            // To ensure the text element is visible
            if (string.IsNullOrEmpty(value))
            {
                s_EditedElement.SetValueByReflection(s_EditedTextAttribute.name, s_DummyText);
            }

            editorLayer.RemoveFromClassList(BuilderConstants.HiddenStyleClassName);

            var textInput = textEditor.Q(TextField.textInputUssName);

            textEditor.value = value;
            textInput.style.unityTextAlign          = textElement.resolvedStyle.unityTextAlign;
            textInput.style.fontSize                = textElement.resolvedStyle.fontSize;
            textInput.style.unityFontStyleAndWeight = textElement.resolvedStyle.unityFontStyleAndWeight;

            textEditor.multiline = value != null && value.Contains("\n");

            GetAlignmentFromTextAnchor(textElement.resolvedStyle.unityTextAlign, out var alignItems, out var justifyContent);

            var textEditorContainer = textEditor.parent;

            textEditorContainer.style.paddingLeft    = s_EditedTextElement.resolvedStyle.paddingLeft;
            textEditorContainer.style.paddingTop     = s_EditedTextElement.resolvedStyle.paddingTop;
            textEditorContainer.style.paddingRight   = s_EditedTextElement.resolvedStyle.paddingRight;
            textEditorContainer.style.paddingBottom  = s_EditedTextElement.resolvedStyle.paddingBottom;
            textEditorContainer.style.alignItems     = alignItems;
            textEditorContainer.style.justifyContent = justifyContent;
            UpdateTextEditorGeometry();
            textElement.RegisterCallback <GeometryChangedEvent>(OnTextElementGeometryChanged);

            textEditor.schedule.Execute(a => textInput.Focus());
            textEditor.SelectAll();

            textInput.RegisterCallback <FocusOutEvent>(OnFocusOutEvent);
            textEditor.RegisterCallback <ChangeEvent <string> >(OnTextChanged);
        }
Beispiel #23
0
        public override void CreateUI()
        {
            var root = rootVisualElement;

            titleContent       = GetLocalizedTitleContent();
            saveChangesMessage = BuilderConstants.SaveDialogSaveChangesPromptMessage;

            // Load assets.
            var builderTemplate = BuilderPackageUtilities.LoadAssetAtPath <VisualTreeAsset>(BuilderConstants.UIBuilderPackagePath + "/Builder.uxml");

            // Load templates.
            builderTemplate.CloneTree(root);

            // Create overlay painter.
            m_HighlightOverlayPainter = new HighlightOverlayPainter();

            // Fetch the tooltip previews.
            var styleSheetsPaneTooltipPreview = root.Q <BuilderTooltipPreview>("stylesheets-pane-tooltip-preview");
            var libraryTooltipPreview         = root.Q <BuilderTooltipPreview>("library-tooltip-preview");

            // Create selection.
            m_Selection = new BuilderSelection(root, this);

            // Create Element Context Menu Manipulator
            var contextMenuManipulator = new BuilderElementContextMenu(this, selection);

            // Create viewport first.
            m_Viewport = new BuilderViewport(this, selection, contextMenuManipulator);
            selection.documentRootElement = m_Viewport.documentRootElement;
            var overlayHelper = viewport.Q <OverlayPainterHelperElement>();

            overlayHelper.painter = m_HighlightOverlayPainter;

            // Create the rest of the panes.
            var classDragger       = new BuilderClassDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker);
            var styleSheetsDragger = new BuilderStyleSheetsDragger(this, root, selection);
            var styleSheetsPane    = new BuilderStyleSheets(this, m_Viewport, selection, classDragger, styleSheetsDragger, m_HighlightOverlayPainter, styleSheetsPaneTooltipPreview);
            var hierarchyDragger   = new BuilderHierarchyDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker)
            {
                builderStylesheetRoot = styleSheetsPane.container
            };

            m_Hierarchy = new BuilderHierarchy(this, m_Viewport, selection, classDragger, hierarchyDragger, contextMenuManipulator, m_HighlightOverlayPainter);

            var libraryDragger = new BuilderLibraryDragger(this, root, selection, m_Viewport, m_Viewport.parentTracker, hierarchy.container, libraryTooltipPreview)
            {
                builderStylesheetRoot = styleSheetsPane.container
            };

            m_Viewport.viewportDragger.builderHierarchyRoot = hierarchy.container;
            m_Library     = new BuilderLibrary(this, m_Viewport, selection, libraryDragger, libraryTooltipPreview);
            m_Inspector   = new BuilderInspector(this, selection, m_HighlightOverlayPainter);
            m_Toolbar     = new BuilderToolbar(this, selection, m_Viewport, hierarchy, m_Library, m_Inspector, libraryTooltipPreview);
            m_UxmlPreview = new BuilderUxmlPreview(this);
            m_UssPreview  = new BuilderUssPreview(this, selection);
            root.Q("viewport").Add(m_Viewport);
            m_Viewport.toolbar.Add(m_Toolbar);
            root.Q("library").Add(m_Library);
            root.Q("style-sheets").Add(styleSheetsPane);
            root.Q("hierarchy").Add(hierarchy);
            root.Q("uxml-preview").Add(m_UxmlPreview);
            root.Q("uss-preview").Add(m_UssPreview);
            root.Q("inspector").Add(m_Inspector);

            // Init selection.
            selection.AssignNotifiers(new IBuilderSelectionNotifier[]
            {
                document,
                m_Viewport,
                styleSheetsPane,
                hierarchy,
                m_Inspector,
                m_Library,
                m_UxmlPreview,
                m_UssPreview,
                m_Toolbar,
                m_Viewport.parentTracker,
                m_Viewport.resizer,
                m_Viewport.mover,
                m_Viewport.anchorer,
                m_Viewport.selectionIndicator
            });

            // Command Handler
            commandHandler.RegisterPane(styleSheetsPane);
            commandHandler.RegisterPane(hierarchy);
            commandHandler.RegisterPane(m_Viewport);
            commandHandler.RegisterToolbar(m_Toolbar);

            m_MiddleSplitView = rootVisualElement.Q <TwoPaneSplitView>("middle-column");
            m_MiddleSplitView.RegisterCallback <GeometryChangedEvent>(OnFirstDisplay);

            OnEnableAfterAllSerialization();
        }
        public BuilderToolbar(
            BuilderPaneWindow paneWindow,
            BuilderSelection selection,
            ModalPopup saveDialog,
            BuilderViewport viewport,
            BuilderExplorer explorer,
            BuilderLibrary library,
            BuilderInspector inspector,
            BuilderTooltipPreview tooltipPreview)
        {
            m_PaneWindow     = paneWindow;
            m_Selection      = selection;
            m_SaveDialog     = saveDialog;
            m_Viewport       = viewport;
            m_Explorer       = explorer;
            m_Library        = library;
            m_Inspector      = inspector;
            m_TooltipPreview = tooltipPreview;

            // Query the UI
            m_SaveDialogUxmlPathField      = m_SaveDialog.Q <TextField>("save-dialog-uxml-path");
            m_SaveDialogUxmlLocationButton = m_SaveDialog.Q <Button>("save-dialog-uxml-location-button");
            m_SaveDialogUssPathField       = m_SaveDialog.Q <TextField>("save-dialog-uss-path");
            m_SaveDialogUssLocationButton  = m_SaveDialog.Q <Button>("save-dialog-uss-location-button");
            m_SaveDialogSaveButton         = m_SaveDialog.Q <Button>("save-dialog-save-button");
            m_SaveDialogCancelButton       = m_SaveDialog.Q <Button>("save-dialog-cancel-button");
            m_SaveDialogTitleLabel         = m_SaveDialog.Q <Label>("title");

            m_SaveDialogUxmlPathField.RegisterValueChangedCallback(OnUxmlPathFieldChange);
            m_SaveDialogUssPathField.RegisterValueChangedCallback(OnUssPathFieldChange);

            m_SaveDialogSaveButton.clickable.clicked         += SaveDocument;
            m_SaveDialogCancelButton.clickable.clicked       += m_SaveDialog.Hide;
            m_SaveDialogUxmlLocationButton.clickable.clicked += OnUxmlLocationButtonClick;
            m_SaveDialogUssLocationButton.clickable.clicked  += OnUssLocationButtonClick;

            var saveDialogValidationBoxContainer = m_SaveDialog.Q("save-dialog-validation-box");

            m_SaveDialogValidationBox = new IMGUIContainer(DrawSaveDialogValidationMessage);
            m_SaveDialogValidationBox.style.overflow = Overflow.Hidden;
            saveDialogValidationBoxContainer.Add(m_SaveDialogValidationBox);

            var template = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(
                BuilderConstants.UIBuilderPackagePath + "/BuilderToolbar.uxml");

            template.CloneTree(this);

            // File Menu
            m_FileMenu = this.Q <ToolbarMenu>("file-menu");
            SetUpFileMenu();

            // Preview Button
            var previewButton = this.Q <ToolbarToggle>("preview-button");

            previewButton.RegisterValueChangedCallback(TogglePreviewMode);

            m_CanvasThemeMenu = this.Q <ToolbarMenu>("canvas-theme-menu");
            SetUpCanvasThemeMenu();
            ChangeCanvasTheme(document.currentCanvasTheme);
            UpdateCanvasThemeMenuStatus();

            // Track unsaved changes state change.
            document.unsavedChangesStateChanged = SetViewportSubTitle;
            SetViewportSubTitle();

            // Get Builder package version.
            var packageInfo = PackageInfo.FindForAssetPath("Packages/" + BuilderConstants.BuilderPackageName);

            if (packageInfo == null)
            {
                m_BuilderPackageVersion = null;
            }
            else
            {
                m_BuilderPackageVersion = packageInfo.version;
            }

            RegisterCallback <AttachToPanelEvent>(RegisterCallbacks);
        }