// For tests only. static string DisplaySaveFileDialogForUSS() { var path = BuilderDialogsUtility.DisplaySaveFileDialog( "Save USS File", null, null, "uss"); return(path); }
internal static string GenerateUXML(this VisualTreeAsset vta, string vtaPath, bool writingToFile = false) { string result = null; try { result = VisualTreeAssetToUXML.GenerateUXML(vta, vtaPath, writingToFile); } catch (Exception ex) { if (!vta.name.Contains(BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix)) { var message = string.Format(BuilderConstants.InvalidUXMLDialogMessage, vta.name); BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidUXMLDialogTitle, message); vta.name = vta.name + BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix; } else { var name = vta.name.Replace(BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix, string.Empty); var message = string.Format(BuilderConstants.InvalidUXMLDialogMessage, name); Builder.ShowWarning(message); } Debug.LogError(ex.Message + "\n" + ex.StackTrace); } return(result); }
internal static string GenerateUSS(this StyleSheet styleSheet) { string result = null; try { result = StyleSheetToUss.ToUssString(styleSheet); } catch (Exception ex) { if (!styleSheet.name.Contains(BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix)) { var message = string.Format(BuilderConstants.InvalidUSSDialogMessage, styleSheet.name); BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidUSSDialogTitle, message); styleSheet.name = styleSheet.name + BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix; } else { var name = styleSheet.name.Replace(BuilderConstants.InvalidUXMLOrUSSAssetNameSuffix, string.Empty); var message = string.Format(BuilderConstants.InvalidUSSDialogMessage, name); Builder.ShowWarning(message); } Debug.LogError(ex.Message + "\n" + ex.StackTrace); } return(result); }
protected override void PerformAction(VisualElement destination, DestinationPane pane, Vector2 localMousePosition, int index = -1) { // We should have an item reference here if the OnDragStart() worked. var item = m_LibraryItem; var itemVTA = item.sourceAsset; if (!paneWindow.document.WillCauseCircularDependency(itemVTA)) { BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidWouldCauseCircularDependencyMessage, BuilderConstants.InvalidWouldCauseCircularDependencyMessageDescription, null); return; } destination.RemoveMinSizeSpecialElement(); // Determine if it applies and use Absolute Island insertion. if (BuilderProjectSettings.enableAbsolutePositionPlacement && pane == DestinationPane.Viewport && m_DragPreviewLastParent == documentRootElement && index < 0) { m_DragPreviewLastParent = BuilderPlacementUtilities.CreateAbsoluteIsland(paneWindow, documentRootElement, localMousePosition); } // Add VisualElement to Canvas. m_DragPreviewElement.RemoveFromClassList(s_DragPreviewElementClassName); if (index < 0) { m_DragPreviewLastParent.Add(m_DragPreviewElement); } else { m_DragPreviewLastParent.Insert(index, m_DragPreviewElement); } // Create equivalent VisualElementAsset. if (item.makeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset( paneWindow.document, m_DragPreviewElement, index); } else { BuilderAssetUtilities.AddElementToAsset( paneWindow.document, m_DragPreviewElement, item.makeElementAssetCallback, index); } selection.NotifyOfHierarchyChange(null); selection.NotifyOfStylingChange(null); selection.Select(null, m_DragPreviewElement); // Commit to the preview element as the final element. // This will stop the ResetDragPreviewElement() from calling // RemoveFromHierarchy() on it. m_DragPreviewElement = null; // If we dragged into the Viewport, focus the Viewport. if (pane == DestinationPane.Viewport) { viewport.pane.Focus(); } }
protected void AddItemToTheDocument(BuilderLibraryTreeItem item) { // If this is the uxml file entry of the currently open file, don't allow // the user to instantiate it (infinite recursion) or re-open it. var listOfOpenDocuments = m_PaneWindow.document.openUXMLFiles; bool isCurrentDocumentOpen = listOfOpenDocuments.Any(doc => doc.uxmlFileName == item.name); if (isCurrentDocumentOpen) { return; } if (m_PaneWindow.document.WillCauseCircularDependency(item.sourceAsset)) { BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidWouldCauseCircularDependencyMessage, BuilderConstants.InvalidWouldCauseCircularDependencyMessageDescription, null); return; } var newElement = item.makeVisualElementCallback?.Invoke(); if (newElement == null) { return; } if (item.makeElementAssetCallback != null && newElement is TemplateContainer tempContainer) { if (!BuilderAssetUtilities.ValidateAsset(item.sourceAsset, item.sourceAssetPath)) { return; } } var activeVTARootElement = m_DocumentRootElement.Query().Where(e => e.GetVisualTreeAsset() == m_PaneWindow.document.visualTreeAsset).First(); if (activeVTARootElement == null) { Debug.LogError("UI Builder has a bug. Could not find document root element for currently active open UXML document."); return; } activeVTARootElement.Add(newElement); if (item.makeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset(m_PaneWindow.document, newElement); } else { BuilderAssetUtilities.AddElementToAsset( m_PaneWindow.document, newElement, item.makeElementAssetCallback); } m_Selection.NotifyOfHierarchyChange(); m_Selection.Select(null, newElement); }
internal bool SaveNewTemplateFileFromHierarchy(string newTemplatePath, string uxml) { var isReplacingFile = File.Exists(newTemplatePath); bool isReplacingFileInHierarchy = false; if (isReplacingFile) { var replacedVTA = EditorGUIUtility.Load(newTemplatePath) as VisualTreeAsset; isReplacingFileInHierarchy = replacedVTA.TemplateExists(m_VisualTreeAsset); if (isReplacingFileInHierarchy && hasUnsavedChanges) { // If we are replacing an element in the hierarchy and there is unsaved changes, // we need to save to make sure we don't lose any elements var saveUnsavedChanges = BuilderDialogsUtility.DisplayDialog( BuilderConstants.SaveDialogSaveChangesPromptTitle, BuilderConstants.SaveDialogReplaceWithNewTemplateMessage, BuilderConstants.DialogSaveActionOption, BuilderConstants.DialogCancelOption); if (saveUnsavedChanges) { var wasDocumentSaved = SaveUnsavedChanges(); if (!wasDocumentSaved) { // Save failed Debug.LogError("Saving the current template failed. New template will not be created."); return(false); } } else { // Save cancelled return(false); } } } if (isReplacingFileInHierarchy) { // This is necessary to make sure we don't show the external changes popup // since we are creating a new template m_DocumentBeingSavedExplicitly = true; } File.WriteAllText(newTemplatePath, uxml); AssetDatabase.Refresh(); if (isReplacingFileInHierarchy) { m_DocumentBeingSavedExplicitly = false; } return(true); }
static public bool WriteTextFileToDisk(string path, string content) { bool success = FileUtil.WriteTextFileToDisk(path, content, out string message); if (!success) { Debug.LogError(message); BuilderDialogsUtility.DisplayDialog("Save - " + path, message, "Ok"); } return(success); }
public bool CheckForUnsavedChanges(bool assetModifiedExternally = false) { if (!hasUnsavedChanges) { return(true); } if (assetModifiedExternally) { // TODO: Nothing can be done here yet, other than telling the user // what just happened. Adding the ability to save unsaved changes // after a file has been modified externally will require some // major changes to the document flow. var promptTitle = string.Format(BuilderConstants.SaveDialogExternalChangesPromptTitle, m_Document.uxmlPath); BuilderDialogsUtility.DisplayDialog( promptTitle, BuilderConstants.SaveDialogExternalChangesPromptMessage); return(true); } else { var option = BuilderDialogsUtility.DisplayDialogComplex( BuilderConstants.SaveDialogSaveChangesPromptTitle, BuilderConstants.SaveDialogSaveChangesPromptMessage, BuilderConstants.DialogSaveActionOption, BuilderConstants.DialogCancelOption, BuilderConstants.DialogDontSaveActionOption); switch (option) { // Save case 0: return(SaveUnsavedChanges()); // Cancel case 1: return(false); // Don't Save case 2: RestoreAssetsFromBackup(); return(true); } } return(true); }
protected override void PerformAction(VisualElement destination, DestinationPane pane, int index = -1) { m_DragPreviewElement.RemoveFromClassList(s_DragPreviewElementClassName); destination.RemoveMinSizeSpecialElement(); // We already have the correct index from the preview element that is // already inserted in the hierarchy. The index we get from the arguments // is actually incorrect (off by one) because it will count the // preview element. index = m_DragPreviewLastParent.IndexOf(m_DragPreviewElement); // We should have an item reference here if the OnDragStart() worked. var item = m_LibraryItem; var itemVTA = item.SourceAsset; if (!paneWindow.document.WillCauseCircularDependency(itemVTA)) { BuilderDialogsUtility.DisplayDialog(BuilderConstants.InvalidWouldCauseCircularDependencyMessage, BuilderConstants.InvalidWouldCauseCircularDependencyMessageDescription, null); return; } if (item.MakeElementAssetCallback == null) { BuilderAssetUtilities.AddElementToAsset( paneWindow.document, m_DragPreviewElement, index); } else { BuilderAssetUtilities.AddElementToAsset( paneWindow.document, m_DragPreviewElement, item.MakeElementAssetCallback, index); } selection.NotifyOfHierarchyChange(null); selection.NotifyOfStylingChange(null); selection.Select(null, m_DragPreviewElement); // Commit to the preview element as the final element. // This will stop the ResetDragPreviewElement() from calling // RemoveFromHierarchy() on it. m_DragPreviewElement = null; // If we dragged into the Viewport, focus the Viewport. if (pane == DestinationPane.Viewport) { Viewport.pane.Focus(); } }
public static bool ValidateAsset(VisualTreeAsset asset, string path) { string errorMessage = null; string errorTitle = null; if (asset == null) { if (string.IsNullOrEmpty(path)) { path = "<unspecified>"; } if (path.StartsWith("Packages/")) { errorMessage = $"The asset at path {path} is not a UXML Document.\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 = $"The asset at path {path} is not a UXML Document."; } errorTitle = "Invalid Asset Type"; } else if (asset.importedWithErrors) { if (string.IsNullOrEmpty(path)) { path = AssetDatabase.GetAssetPath(asset); } if (string.IsNullOrEmpty(path)) { path = "<unspecified>"; } errorMessage = string.Format(BuilderConstants.InvalidUXMLDialogMessage, path); errorTitle = BuilderConstants.InvalidUXMLDialogTitle; } if (errorMessage != null) { BuilderDialogsUtility.DisplayDialog(errorTitle, errorMessage, "Ok"); Debug.LogError(errorMessage); return(false); } return(true); }
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); }
bool DeleteElementFromVisualTreeAsset(VisualElement element) { var vea = element.GetVisualElementAsset(); if (vea == null) { return(false); } #if UNITY_2019_4 // Before 2020.1, the only way to attach a StyleSheet to a UXML document was via a <Style> // tag as a child of an element tag. This meant that if there were no elements in the document, // there cannot be any StyleSheets attached to it. Therefore, we need to warn the user when // deleting the last element in the document that they will lose the list of attached StyleSheets // as well. This is something that can be undone via undo so it's not terrible if they say "Yes" // accidentally. // // 2020.1 adds support for the global <Style> tag so this limitation is lifted. However, the // UI Builder does not yet support the global <Style> tag. Plus, even when support to the // UI Builder is added, we still need to maintain support for 2019.3 via this logic. if (m_PaneWindow.document.firstStyleSheet != null && m_PaneWindow.document.visualTreeAsset.WillBeEmptyIfRemovingOne(vea)) { var continueDeletion = BuilderDialogsUtility.DisplayDialog( BuilderConstants.DeleteLastElementDialogTitle, BuilderConstants.DeleteLastElementDialogMessage, "Yes", "Cancel"); if (!continueDeletion) { return(false); } BuilderAssetUtilities.DeleteElementFromAsset(m_PaneWindow.document, element); m_PaneWindow.OnEnableAfterAllSerialization(); } else #endif { BuilderAssetUtilities.DeleteElementFromAsset(m_PaneWindow.document, element); element.RemoveFromHierarchy(); m_Selection.NotifyOfHierarchyChange(); } return(true); }
public bool CheckForUnsavedChanges() { if (!hasUnsavedChanges) { return(true); } var option = BuilderDialogsUtility.DisplayDialogComplex( BuilderConstants.SaveDialogSaveChangesPromptTitle, BuilderConstants.SaveDialogSaveChangesPromptMessage, BuilderConstants.DialogSaveActionOption, BuilderConstants.DialogCancelOption, BuilderConstants.DialogDontSaveActionOption); switch (option) { // Save case 0: if (!string.IsNullOrEmpty(uxmlPath) && !string.IsNullOrEmpty(ussPath)) { SaveNewDocument(uxmlPath, ussPath, null, false); return(true); } else { var builderWindow = Builder.ActiveWindow; if (builderWindow == null) { builderWindow = Builder.ShowWindow(); } builderWindow.toolbar.PromptSaveDocumentDialog(); return(false); } // Cancel case 1: return(false); // Don't Save case 2: return(true); } return(true); }
bool IsFileActionCompatible(string assetPath, string actionName) { if (assetPath.Equals(document.uxmlPath) || document.ussPaths.Contains(assetPath)) { var fileName = Path.GetFileName(assetPath); var acceptAction = BuilderDialogsUtility.DisplayDialog(BuilderConstants.ErrorDialogNotice, string.Format(BuilderConstants.ErrorIncompatibleFileActionMessage, actionName, fileName), BuilderConstants.DialogDiscardOption, string.Format(BuilderConstants.DialogAbortActionOption, actionName.ToPascalCase())); if (acceptAction) { NewDocument(false); } return(acceptAction); } return(true); }
StyleSheet GetOrCreateOrAddMainStyleSheet() { // Get StyleSheet. var mainStyleSheet = m_PaneWindow.document.activeStyleSheet; if (mainStyleSheet == null) { var option = BuilderDialogsUtility.DisplayDialogComplex( BuilderConstants.ExtractInlineStylesNoUSSDialogTitle, BuilderConstants.ExtractInlineStylesNoUSSDialogMessage, BuilderConstants.ExtractInlineStylesNoUSSDialogNewUSSOption, BuilderConstants.ExtractInlineStylesNoUSSDialogExistingUSSOption, BuilderConstants.DialogCancelOption); switch (option) { // New case 0: if (!BuilderStyleSheetsUtilities.CreateNewUSSAsset(m_PaneWindow)) { return(null); } break; // Existing case 1: if (!BuilderStyleSheetsUtilities.AddExistingUSSToAsset(m_PaneWindow)) { return(null); } break; // Cancel case 2: return(null); } mainStyleSheet = m_PaneWindow.document.activeStyleSheet; } return(mainStyleSheet); }
bool IsFileActionCompatible(string assetPath, string actionName) { if (IsAssetUsedInDocument(document, assetPath)) { var fileName = Path.GetFileName(assetPath); var acceptAction = BuilderDialogsUtility.DisplayDialog(BuilderConstants.ErrorDialogNotice, string.Format(BuilderConstants.ErrorIncompatibleFileActionMessage, actionName, fileName), string.Format(BuilderConstants.DialogDiscardOption, actionName.ToPascalCase()), string.Format(BuilderConstants.DialogAbortActionOption, actionName.ToPascalCase())); if (acceptAction) { // Open a new, empty document NewDocument(false); } return(acceptAction); } return(true); }
private void OnEditButton() { if (BuilderExternalPackages.is2DSpriteEditorInstalled) { // Open 2D Sprite Editor with current image loaded BuilderExternalPackages.Open2DSpriteEditor((Object)value); return; } // Handle the missing 2D Sprite Editor package case. if (BuilderDialogsUtility.DisplayDialog( k_No2DSpriteEditorPackageInstalledTitle, k_No2DSpriteEditorPackageInstalledMessage, "Install", "Cancel")) { if (!Install2DSpriteEditorPackage()) { Application.OpenURL(k_2DSpriteEditorInstallationURL); } } }
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 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 bool SaveNewDocument( VisualElement documentRootElement, bool isSaveAs, out bool needsFullRefresh, string manualUxmlPath = null) { needsFullRefresh = false; ClearUndo(); // Re-use or ask the user for the UXML path. var newUxmlPath = uxmlPath; if (string.IsNullOrEmpty(newUxmlPath) || isSaveAs) { if (!string.IsNullOrEmpty(manualUxmlPath)) { newUxmlPath = manualUxmlPath; } else { newUxmlPath = BuilderDialogsUtility.DisplaySaveFileDialog("Save UXML", null, null, "uxml"); if (newUxmlPath == null) // User cancelled the save dialog. { return(false); } } } // Save USS files. foreach (var openUSSFile in m_OpenUSSFiles) { openUSSFile.SaveToDisk(visualTreeAsset); } { // Save UXML file. // Need to save a backup before the AssetDatabase.Refresh(). if (m_VisualTreeAssetBackup == null) { m_VisualTreeAssetBackup = m_VisualTreeAsset.DeepCopy(); } else { m_VisualTreeAsset.DeepOverwrite(m_VisualTreeAssetBackup); } WriteUXMLToFile(newUxmlPath); } // Once we wrote all the files to disk, we refresh the DB and reload // the files from the AssetDatabase. m_DocumentBeingSavedExplicitly = true; try { AssetDatabase.Refresh(); } finally { m_DocumentBeingSavedExplicitly = false; } // Check if any USS assets have changed reload them. foreach (var openUSSFile in m_OpenUSSFiles) { needsFullRefresh |= openUSSFile.PostSaveToDiskChecksAndFixes(); } { // Check if the UXML asset has changed and reload it. m_VisualTreeAsset = AssetDatabase.LoadAssetAtPath <VisualTreeAsset>(newUxmlPath); needsFullRefresh |= m_VisualTreeAsset != m_VisualTreeAssetBackup; } if (needsFullRefresh) { // Copy previous document settings. if (m_Settings != null) { m_Settings.UxmlGuid = AssetDatabase.AssetPathToGUID(newUxmlPath); m_Settings.UxmlPath = newUxmlPath; m_Settings.SaveSettingsToDisk(); } { // Fix up UXML asset. // To get all the selection markers into the new assets. m_VisualTreeAssetBackup.DeepOverwrite(m_VisualTreeAsset); // Reset asset name. m_VisualTreeAsset.name = Path.GetFileNameWithoutExtension(newUxmlPath); m_VisualTreeAsset.ConvertAllAssetReferencesToPaths(); m_OpenendVisualTreeAssetOldPath = newUxmlPath; } if (documentRootElement != null) { ReloadDocumentToCanvas(documentRootElement); } } hasUnsavedChanges = false; return(true); }
public bool SaveNewDocument( VisualElement documentRootElement, bool isSaveAs, out bool needsFullRefresh, string manualUxmlPath = null) { needsFullRefresh = false; ClearUndo(); // Re-use or ask the user for the UXML path. var newUxmlPath = uxmlPath; if (string.IsNullOrEmpty(newUxmlPath) || isSaveAs) { if (!string.IsNullOrEmpty(manualUxmlPath)) { newUxmlPath = manualUxmlPath; } else { newUxmlPath = BuilderDialogsUtility.DisplaySaveFileDialog("Save UXML", null, null, "uxml"); if (newUxmlPath == null) // User cancelled the save dialog. { return(false); } } } // Save USS files. foreach (var openUSSFile in m_OpenUSSFiles) { openUSSFile.SaveToDisk(visualTreeAsset); } // Save UXML files // Saving all open UXML files to ensure references correct upon changes in child documents. foreach (var openUXMLFile in openUXMLFiles) { openUXMLFile.PreSaveSyncBackup(); } WriteUXMLToFile(newUxmlPath); // Once we wrote all the files to disk, we refresh the DB and reload // the files from the AssetDatabase. m_DocumentBeingSavedExplicitly = true; try { AssetDatabase.Refresh(); } finally { m_DocumentBeingSavedExplicitly = false; } // Check if any USS assets have changed reload them. foreach (var openUSSFile in m_OpenUSSFiles) { needsFullRefresh |= openUSSFile.PostSaveToDiskChecksAndFixes(); } // Check if any UXML assets have changed and reload them. // Saving all open UXML files to ensure references correct upon changes in child subdocuments. foreach (var openUXMLFile in openUXMLFiles) { needsFullRefresh |= openUXMLFile.PostSaveToDiskChecksAndFixes(this == openUXMLFile ? newUxmlPath : null, needsFullRefresh); } if (needsFullRefresh) { // Copy previous document settings. if (m_Settings != null) { m_Settings.UxmlGuid = AssetDatabase.AssetPathToGUID(newUxmlPath); m_Settings.UxmlPath = newUxmlPath; m_Settings.SaveSettingsToDisk(); } // Reset asset name. m_VisualTreeAsset.name = Path.GetFileNameWithoutExtension(newUxmlPath); m_OpenendVisualTreeAssetOldPath = newUxmlPath; if (documentRootElement != null) { ReloadDocumentToCanvas(documentRootElement); } } hasUnsavedChanges = false; return(true); }
void ExtractLocalStylesToNewClass(string className) { // Get StyleSheet. var mainStyleSheet = m_PaneWindow.document.activeStyleSheet; if (mainStyleSheet == null) { var option = BuilderDialogsUtility.DisplayDialogComplex( BuilderConstants.ExtractInlineStylesNoUSSDialogTitle, BuilderConstants.ExtractInlineStylesNoUSSDialogMessage, BuilderConstants.ExtractInlineStylesNoUSSDialogNewUSSOption, BuilderConstants.ExtractInlineStylesNoUSSDialogExistingUSSOption, BuilderConstants.DialogCancelOption); switch (option) { // New case 0: if (!BuilderStyleSheetsUtilities.CreateNewUSSAsset(m_PaneWindow)) { return; } break; // Existing case 1: if (!BuilderStyleSheetsUtilities.AddExistingUSSToAsset(m_PaneWindow)) { return; } break; // Cancel case 2: return; } mainStyleSheet = m_PaneWindow.document.activeStyleSheet; } PreAddStyleClass(className); // Create new selector in main StyleSheet. var selectorString = BuilderConstants.UssSelectorClassNameSymbol + className; var selectorsRootElement = BuilderSharedStyles.GetSelectorContainerElement(m_Selection.documentElement); var newSelector = BuilderSharedStyles.CreateNewSelector(selectorsRootElement, mainStyleSheet, selectorString); // Transfer all properties from inline styles rule to new selector. mainStyleSheet.TransferRulePropertiesToSelector( newSelector, m_Inspector.styleSheet, m_Inspector.currentRule); // Update VisualTreeAsset. BuilderAssetUtilities.AddStyleClassToElementInAsset( m_PaneWindow.document, currentVisualElement, className); // Overwrite Undo Message. Undo.RegisterCompleteObjectUndo( new Object[] { m_PaneWindow.document.visualTreeAsset, mainStyleSheet }, BuilderConstants.CreateStyleClassUndoMessage); // We actually want to get the notification back and refresh ourselves. m_Selection.NotifyOfStylingChange(null); m_Selection.NotifyOfHierarchyChange(null, currentVisualElement); }
public void CreateTemplateFromHierarchy(VisualElement ve, VisualTreeAsset vta, string path = "") { var veas = new List <VisualElementAsset>(); var vea = ve.GetVisualElementAsset(); veas.Add(vea); if (string.IsNullOrEmpty(path)) { path = BuilderDialogsUtility.DisplaySaveFileDialog("Save UXML", null, ve.name, "uxml"); if (string.IsNullOrEmpty(path)) { // Save dialog cancelled return; } } if (path == m_PaneWindow.document.activeOpenUXMLFile.uxmlPath) { // Path is the same as the active open uxml file. Abort! BuilderDialogsUtility.DisplayDialog( BuilderConstants.InvalidCreateTemplatePathTitle, BuilderConstants.InvalidCreateTemplatePathMessage, BuilderConstants.DialogOkOption); return; } var uxml = VisualTreeAssetToUXML.GenerateUXML(vta, null, veas); if (!m_PaneWindow.document.SaveNewTemplateFileFromHierarchy(path, uxml)) { // New template wasn't saved return; } var parent = ve.parent; var parentVEA = parent.GetVisualElementAsset(); var index = parent.IndexOf(ve); // Delete old element BuilderAssetUtilities.DeleteElementFromAsset(m_PaneWindow.document, ve); ve.RemoveFromHierarchy(); // Replace with new template var newTemplateVTA = EditorGUIUtility.Load(path) as VisualTreeAsset; var newTemplateContainer = newTemplateVTA.CloneTree(); newTemplateContainer.SetProperty(BuilderConstants.LibraryItemLinkedTemplateContainerPathVEPropertyName, path); newTemplateContainer.name = newTemplateVTA.name; parent.Insert(index, newTemplateContainer); BuilderAssetUtilities.AddElementToAsset(m_PaneWindow.document, newTemplateContainer, (inVta, inParent, ve) => { var vea = inVta.AddTemplateInstance(inParent, path) as VisualElementAsset; vea.AddProperty("name", newTemplateVTA.name); ve.SetProperty(BuilderConstants.ElementLinkedInstancedVisualTreeAssetVEPropertyName, newTemplateVTA); return(vea); }, index); m_Selection.Select(null, newTemplateContainer); // Refresh m_Selection.NotifyOfHierarchyChange(); m_PaneWindow.OnEnableAfterAllSerialization(); }
public bool CheckForUnsavedChanges(bool assetModifiedExternally = false) { if (!hasUnsavedChanges) { return(true); } int option = -1; if (assetModifiedExternally) { // TODO: Nothing can be done here yet, other than telling the user // what just happened. Adding the ability to save unsaved changes // after a file has been modified externally will require some // major changes to the document flow. BuilderDialogsUtility.DisplayDialog( BuilderConstants.SaveDialogExternalChangesPromptTitle, BuilderConstants.SaveDialogExternalChangesPromptMessage); return(true); } else { option = BuilderDialogsUtility.DisplayDialogComplex( BuilderConstants.SaveDialogSaveChangesPromptTitle, BuilderConstants.SaveDialogSaveChangesPromptMessage, BuilderConstants.DialogSaveActionOption, BuilderConstants.DialogCancelOption, BuilderConstants.DialogDontSaveActionOption); switch (option) { // Save case 0: if (!string.IsNullOrEmpty(uxmlPath) && !string.IsNullOrEmpty(ussPath)) { SaveNewDocument(uxmlPath, ussPath, null, false); return(true); } else { var builderWindow = Builder.ActiveWindow; if (builderWindow == null) { builderWindow = Builder.ShowWindow(); } builderWindow.toolbar.PromptSaveDocumentDialog(); return(false); } // Cancel case 1: return(false); // Don't Save case 2: RestoreAssetsFromBackup(); return(true); } } return(true); }