private void UpdatePublicUIElementsEntry(Guid rootId, [CanBeNull] string name) { var node = NodeContainer.GetNode((UILibraryAsset)Asset.Asset)[nameof(UILibraryAsset.PublicUIElements)].Target; var index = new Index(rootId); using (var transaction = UndoRedoService.CreateTransaction()) { // update UILibraryAsset's PublicUIElements collection if (string.IsNullOrWhiteSpace(name)) { // Remove the entry if it exists if (node.Indices.Contains(index)) { node.Remove(name, index); UndoRedoService.SetName(transaction, $"Remove '{name}' export from the UILibrary"); } } else { if (!node.Indices.Contains(index)) { // Note: update would probably work, but we want to remove the item when Undo node.Add(name, index); UndoRedoService.SetName(transaction, $"Add '{name}' export to the UILibrary"); } else { node.Update(name, index); UndoRedoService.SetName(transaction, "Update name of export in the UILibrary"); } } } }
private void RemoveSelectedRenderFeatures() { using (var transaction = UndoRedoService.CreateTransaction()) { var toRemove = SelectedRenderFeatures.Cast <RenderFeatureViewModel>().Select(x => x.RenderFeature).ToList(); // Clear selection first, so we don't try to unselect items that don't exist anymore later. SelectedRenderFeatures.Clear(); foreach (var renderFeature in toRemove) { // Find index var index = Asset.Asset.RenderFeatures.IndexOf(renderFeature); if (index < 0) { continue; } // Remove var itemIndex = new NodeIndex(index); renderFeaturesNode.Remove(renderFeature, itemIndex); } UndoRedoService.SetName(transaction, "Delete render feature(s)"); } }
private void RemoveSelectedRenderStages() { using (var transaction = UndoRedoService.CreateTransaction()) { var toRemove = SelectedRenderStages.Cast <RenderStageViewModel>().Select(x => x.RenderStage).ToList(); // Clear selection first, so we don't try to unselect items that don't exist anymore later. SelectedRenderStages.Clear(); foreach (var renderStage in toRemove) { // Find index var index = Asset.Asset.RenderStages.IndexOf(renderStage); if (index < 0) { continue; } // Clear references to this object Asset.PropertyGraph.ClearReferencesToObjects(renderStage.Id.Yield()); // Remove var itemIndex = new NodeIndex(index); renderStagesNode.Remove(renderStage, itemIndex); } UndoRedoService.SetName(transaction, "Delete render stage(s)"); } }
private void RemoveSelectedSharedRenderers() { using (var transaction = UndoRedoService.CreateTransaction()) { var toRemove = SelectedSharedRenderers.OfType <SharedRendererBlockViewModel>().ToList(); // Clear selection first, so we don't try to unselect items that don't exist anymore later. SelectedSharedRenderers.Clear(); foreach (var viewModel in toRemove) { // Find index var index = Asset.Asset.SharedRenderers.IndexOf(viewModel.GetSharedRenderer()); if (index < 0) { continue; } // Remove var itemIndex = new NodeIndex(index); sharedRenderersNode.Remove(viewModel.GetSharedRenderer(), itemIndex); } UndoRedoService.SetName(transaction, "Delete renderer(s)"); } }
private async void CreateSkeleton() { var source = Asset.Source; if (UPath.IsNullOrEmpty(source)) { return; } using (var transaction = UndoRedoService.CreateTransaction()) { var template = Session.FindTemplates(TemplateScope.Asset).SingleOrDefault(x => x.Id == SkeletonFromFileTemplateGenerator.Id); if (template != null) { var viewModel = new TemplateDescriptionViewModel(ServiceProvider, template); var skeleton = (await Session.ActiveAssetView.RunAssetTemplate(viewModel, new[] { source })).SingleOrDefault(); if (skeleton == null) { return; } var skeletonNode = AssetRootNode[nameof(ModelAsset.Skeleton)]; var reference = ContentReferenceHelper.CreateReference <Skeleton>(skeleton); skeletonNode.Update(reference); } UndoRedoService.SetName(transaction, "Create Skeleton"); } }
private void AddTag(string tag) { if (string.IsNullOrWhiteSpace(tag)) { return; } var singleAsset = assetCollection.SelectedAssets.First(); var tagViewModel = Tags.FirstOrDefault(x => x.Name == tag); using (var transaction = UndoRedoService.CreateTransaction()) { int assetCount; modifyingTag = true; if (tagViewModel == null) { tagViewModel = new TagViewModel(this, tag, Enumerable.Empty <AssetViewModel>(), assetCollection.SelectedAssets.Count); // We had the assets to the tag after construction to ensure they will create an operation for the undo stack. tagViewModel.Assets.AddRange(assetCollection.SelectedAssets); assetCount = assetCollection.SelectedAssets.Count; Tags.Add(tagViewModel); } else { var assetsToAdd = assetCollection.SelectedAssets.Where(x => !tagViewModel.Assets.Contains(x)).ToList(); assetCount = assetsToAdd.Count; tagViewModel.Assets.AddRange(assetsToAdd); } string message = $"Added tag '{tag}' to {(assetCount > 1 ? $"{assetCount} assets" : singleAsset.Url)}"; modifyingTag = false; UndoRedoService.SetName(transaction, message); } }
/// <inheritdoc /> protected override ISet <UIElementViewModel> DuplicateSelection() { // save elements to copy var elementsToDuplicate = GetCommonRoots(SelectedItems); // check that the selected elements can be duplicated if (elementsToDuplicate.Any(e => !e.CanDuplicate())) { return(elementsToDuplicate); } // clear selection ClearSelection(); // duplicate the elements var duplicatedElements = new HashSet <UIElementViewModel>(); using (var transaction = UndoRedoService.CreateTransaction()) { duplicatedElements.AddRange(elementsToDuplicate.Select(x => x.Duplicate())); UndoRedoService.SetName(transaction, "Duplicate elements"); } // set selection to new copied elements. SelectedContent.AddRange(duplicatedElements); return(duplicatedElements); }
private void RemoveSelectedCameraSlots() { using (var transaction = UndoRedoService.CreateTransaction()) { var toRemove = SelectedCameraSlots.Cast <GraphicsCompositorCameraSlotsViewModel>().Select(x => x.CameraSlot).ToList(); // Clear selection first, so we don't try to unselect items that don't exist anymore later. SelectedCameraSlots.Clear(); foreach (var viewModel in toRemove) { // Find index var index = Asset.Asset.Cameras.IndexOf(viewModel); if (index < 0) { continue; } // Do not clear references to this object - camera slots in the scene asset should not change automatically! // Remove var itemIndex = new NodeIndex(index); cameraSlotsNode.Remove(viewModel, itemIndex); } UndoRedoService.SetName(transaction, "Delete camera slot(s)"); } }
void IResizingTarget.OnResizingCompleted(ResizingDirection direction, double horizontalChange, double verticalChange) { using (var transaction = UndoRedoService.CreateTransaction()) { OnResizingCompleted(direction, horizontalChange, verticalChange); UndoRedoService.SetName(transaction, "Move control point"); } }
public override async Task Invoke(object parameter) { using (var transaction = UndoRedoService.CreateTransaction()) { await NodeCommand.Execute(node, index, parameter); UndoRedoService.SetName(transaction, ActionName); } }
private void AddNewRenderFeature(AbstractNodeType abstractNodeType) { using (var transaction = UndoRedoService.CreateTransaction()) { var renderFeature = abstractNodeType.GenerateValue(null); renderFeaturesNode.Add(renderFeature); UndoRedoService.SetName(transaction, "Create new render feature"); } }
private void AddNewCameraSlot() { using (var transaction = UndoRedoService.CreateTransaction()) { var cameraSlot = new SceneCameraSlot(); cameraSlotsNode.Add(cameraSlot); UndoRedoService.SetName(transaction, "Create new camera slot"); } }
private void AddNewRenderStage() { using (var transaction = UndoRedoService.CreateTransaction()) { var renderStage = new RenderStage(); renderStagesNode.Add(renderStage); UndoRedoService.SetName(transaction, "Create new render stage"); } }
void IAddChildViewModel.AddChildren(IReadOnlyCollection <object> children, AddChildModifiers modifiers) { int directoriesMoved = 0; int assetsMoved = 0; DirectoryViewModel singleDirectoryMoved = null; AssetViewModel singleAssetMoved = null; using (var transaction = UndoRedoService.CreateTransaction()) { foreach (var child in children) { var directory = child as DirectoryViewModel; var asset = child as AssetViewModel; if (directory != null) { ++directoriesMoved; singleDirectoryMoved = directoriesMoved == 1 ? directory : null; var hierarchy = new List <DirectoryBaseViewModel>(); directory.GetDirectoryHierarchy(hierarchy); assetsMoved += hierarchy.Select(x => x.Assets.Count).Sum(); singleAssetMoved = assetsMoved == 1 ? hierarchy.SelectMany(x => x.Assets).FirstOrDefault() : null; directory.Parent = this; } if (asset != null) { ++assetsMoved; singleAssetMoved = assetsMoved == 1 ? asset : null; Package.MoveAsset(asset, this); } } string message = ""; if (singleDirectoryMoved != null) { message = $"Move directory '{singleDirectoryMoved.Name}'"; } else if (directoriesMoved > 1) { message = $"Move {directoriesMoved} directories"; } if (assetsMoved > 0) { message += message.Length > 0 ? " and " : "Move "; if (singleAssetMoved != null) { message += $"asset '{singleAssetMoved.Url}'"; } else { message += $"{assetsMoved} assets"; } } UndoRedoService.SetName(transaction, message); } }
private void RemoveSelectedProperties() { using (var transaction = UndoRedoService.CreateTransaction()) { foreach (var property in SelectedProperties.Cast <NodeViewModel>().Select(x => (Property)x.NodeValue).ToList()) { Asset.RemoveProperty(property); } UndoRedoService.SetName(transaction, "Delete propertie(s)"); } }
private void GroupInto(IUIElementFactory factory) { var targetPanelType = (factory as UIElementFromSystemLibrary)?.Type; if (targetPanelType == null) { throw new NotSupportedException("Grouping elements into a user library type isn't supported."); } if (!typeof(Panel).IsAssignableFrom(targetPanelType)) { throw new ArgumentException(@"The target type isn't a panel", nameof(targetPanelType)); } if (SelectedContent.Count == 0) { return; } // Ensure that the selected elements are sibling. var allParents = SelectedItems.Select(x => x.Parent).OfType <UIHierarchyItemViewModel>().ToList(); var parent = allParents[0]; if (allParents.Any(x => x != parent)) { throw new InvalidOperationException("This operation can only be executed on a selection of sibling elements."); } using (var transaction = UndoRedoService.CreateTransaction()) { var children = SelectedItems.ToList(); // Create the new panel into which we'll insert the selection var newPanel = (Panel)Activator.CreateInstance(targetPanelType); var newPanelDesign = new UIElementDesign(newPanel); // Create a hierarchy containing all children and the panel var hierarchy = UIAssetPropertyGraph.CloneSubHierarchies(Asset.Session.AssetNodeContainer, Asset.Asset, children.Select(c => c.Id.ObjectId), SubHierarchyCloneFlags.None, out _); hierarchy.RootParts.Add(newPanel); hierarchy.Parts.Add(newPanelDesign); // Remove all children from their partDesign panel. foreach (var child in children) { child.Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(child.UIElementDesign); } // Add the new panel in place of the selected content. parent.Asset.InsertUIElement(hierarchy.Parts, newPanelDesign, (parent as UIElementViewModel)?.AssetSideUIElement); // Add the children into the new panel. foreach (var child in children) { parent.Asset.InsertUIElement(hierarchy.Parts, hierarchy.Parts[child.Id.ObjectId], newPanel); } UndoRedoService.SetName(transaction, $"Group into {targetPanelType.Name}"); } }
public override async Task Invoke(object parameter) { using (var transaction = UndoRedoService?.CreateTransaction()) { firstCommand?.NodeCommand.StartCombinedInvoke(); foreach (var command in commands) { await command.Invoke(parameter); } firstCommand?.NodeCommand.EndCombinedInvoke(); UndoRedoService?.SetName(transaction, ActionName); } }
private void RemoveSelectedFunction() { if (SelectedMethod == null) { return; } using (var transaction = UndoRedoService.CreateTransaction()) { UndoRedoService.SetName(transaction, $"Delete function {SelectedMethod.Method.Name}"); Asset.RemoveMethod(SelectedMethod.Method); } }
private async Task RegenerateSlots() { using (var transaction = UndoRedoService.CreateTransaction()) { // Regenerate slots foreach (var function in Asset.Methods) { await function.RegenerateSlots(); } UndoRedoService.SetName(transaction, "Regenerated slots (code update)"); } }
public void Delete() { if (Package.IsSystem) { // Note: this should never happen (see comments in method SessionViewModel.DeleteSelectedSolutionItems) throw new InvalidOperationException("System packages cannot be deleted."); } using (var transaction = UndoRedoService.CreateTransaction()) { string message = $"Delete package '{Name}'"; IsDeleted = true; UndoRedoService.SetName(transaction, message); } }
private void Rename(UFile packagePath) { using (var transaction = UndoRedoService.CreateTransaction()) { var previousPath = PackagePath; PackagePath = packagePath; if (previousPath != PackagePath) { IsEditing = false; } UndoRedoService.SetName(transaction, $"Rename package '{previousPath.GetFileNameWithoutExtension()}' to '{packagePath.GetFileNameWithoutExtension()}'"); } }
public async Task AddExistingProject() { var fileDialog = ServiceProvider.Get <IEditorDialogService>().CreateFileOpenModalDialog(); fileDialog.Filters.Add(new FileDialogFilter("Visual Studio C# project", "csproj")); fileDialog.InitialDirectory = Session.SolutionPath; var result = await fileDialog.ShowModal(); var projectPath = fileDialog.FilePaths.FirstOrDefault(); if (result == DialogResult.Ok && projectPath != null) { var loggerResult = new LoggerResult(); var cancellationSource = new CancellationTokenSource(); var workProgress = new WorkProgressViewModel(ServiceProvider, loggerResult) { Title = "Importing package...", KeepOpen = KeepOpen.OnWarningsOrErrors, IsIndeterminate = true, IsCancellable = false }; using (var transaction = UndoRedoService.CreateTransaction()) { workProgress.RegisterProgressStatus(loggerResult, true); ServiceProvider.Get <IEditorDialogService>().ShowProgressWindow(workProgress, 500); await Task.Run(() => { try { Package.AddExistingProject(projectPath, loggerResult); } catch (Exception e) { loggerResult.Error("An exception occurred while importing the project", e); } }, cancellationSource.Token); RefreshPackageReferences(); UndoRedoService.SetName(transaction, $"Import project '{new UFile(projectPath).GetFileNameWithoutExtension()}'"); } // Notify that the task is finished await workProgress.NotifyWorkFinished(cancellationSource.IsCancellationRequested, loggerResult.HasErrors); } }
public override async Task Invoke(object parameter) { using (var transaction = UndoRedoService?.CreateTransaction()) { var modelNode = NodePath.GetNode(); if (modelNode == null) { throw new InvalidOperationException("Unable to retrieve the node on which to apply the redo operation."); } await NodeCommand.Execute(modelNode, Index, parameter); UndoRedoService?.SetName(transaction, ActionName); } }
public List <AssetViewModel> PasteAssets(List <AssetItem> assets, [CanBeNull] ProjectViewModel project) { var viewModels = new List <AssetViewModel>(); // Don't touch the action stack in this case. if (assets.Count == 0) { return(viewModels); } var fixedAssets = new List <AssetItem>(); using (var transaction = UndoRedoService.CreateTransaction()) { // Clean collision by renaming pasted asset if an asset with the same name already exists in that location. AssetCollision.Clean(null, assets, fixedAssets, AssetResolver.FromPackage(Package), false, false); // Temporarily add the new asset to the package fixedAssets.ForEach(x => Package.Assets.Add(x)); // Find which assets are referencing the pasted assets in order to fix the reference link. var assetsToFix = GetReferencers(Session.DependencyManager, Session, fixedAssets); // Remove temporarily added assets - they will be properly re-added with the correct action stack entry when creating the view model fixedAssets.ForEach(x => Package.Assets.Remove(x)); // Create directories and view models, actually add assets to package. foreach (var asset in fixedAssets) { var location = asset.Location.GetFullDirectory() ?? ""; var assetDirectory = project == null? GetOrCreateAssetDirectory(location, true) : project.GetOrCreateProjectDirectory(location, true); var assetViewModel = CreateAsset(assetDirectory, asset, true, null); viewModels.Add(assetViewModel); } // Fix references in the assets that references what we pasted. // We wrap this operation in an action item so the action stack can properly re-execute it. var fixReferencesAction = new FixAssetReferenceOperation(assetsToFix, false, true); fixReferencesAction.FixAssetReferences(); UndoRedoService.PushOperation(fixReferencesAction); UndoRedoService.SetName(transaction, "Paste assets"); } return(viewModels); }
void IResizingTarget.OnResizingCompleted(ResizingDirection direction, double horizontalChange, double verticalChange) { if (resizingTransaction == null || resizingContext == null) { throw new InvalidOperationException("No resize operation in progress."); } // The synchronization context has changed here, we must signal we intentionnally continue an existing transaction. resizingTransaction.Continue(); var transactionName = ComputeTransactionName(direction, horizontalChange, verticalChange); UndoRedoService.SetName(resizingTransaction, transactionName); resizingTransaction.Complete(); resizingTransaction = null; resizingContext = null; }
/// <summary> /// Deletes this directory and all its subdirectories and contained assets. /// </summary> public override void Delete() { string message = $@"Delete folder ""{Path}"""; var previousProject = Package; using (var transaction = UndoRedoService.CreateTransaction()) { var hierarchy = new List <DirectoryBaseViewModel>(); GetDirectoryHierarchy(hierarchy); foreach (var asset in hierarchy.SelectMany(directory => directory.Assets)) { asset.IsDeleted = true; } Parent = null; UndoRedoService.SetName(transaction, message); } previousProject.CheckConsistency(); }
public void AddDependency(PackageViewModel packageViewModel) { using (var transaction = UndoRedoService.CreateTransaction()) { PackageReferenceViewModel reference; if (packageViewModel.Package.IsSystem) { var dependency = new PackageDependency(packageViewModel.Name, new PackageVersionRange(packageViewModel.Package.Meta.Version)); reference = new StorePackageReferenceViewModel(dependency, packageViewModel, this, Dependencies, true); } else { var dependency = new PackageReference(packageViewModel.Package.Id, packageViewModel.Package.FullPath); reference = new LocalPackageReferenceViewModel(dependency, packageViewModel, this, Dependencies, true); } UndoRedoService.SetName(transaction, $"Add dependency to package '{reference.Name}'"); } }
/// <inheritdoc /> protected override async Task Delete() { var elementsToDelete = GetCommonRoots(SelectedItems); var ask = UIEditorSettings.AskBeforeDeletingUIElements.GetValue(); if (ask) { var confirmMessage = Tr._p("Message", "Are you sure you want to delete this UI element?"); if (elementsToDelete.Count > 1) { confirmMessage = string.Format(Tr._p("Message", "Are you sure you want to delete these {0} UI elements?"), elementsToDelete.Count); } var buttons = DialogHelper.CreateButtons(new[] { Tr._p("Button", "Delete"), Tr._p("Button", "Cancel") }, 1, 2); var result = await ServiceProvider.Get <IDialogService>().CheckedMessageBox(confirmMessage, false, DialogHelper.DontAskAgain, buttons, MessageBoxImage.Question); if (result.Result != 1) { return; } if (result.IsChecked == true) { UIEditorSettings.AskBeforeDeletingUIElements.SetValue(false); UIEditorSettings.Save(); } } var hadActiveRoot = elementsToDelete.Any(x => ReferenceEquals(x, ActiveRoot)); var asset = elementsToDelete.First().Asset; // all selected items are from the same asset using (var transaction = UndoRedoService.CreateTransaction()) { ClearSelection(); HashSet <Tuple <Guid, Guid> > mapping; asset.AssetHierarchyPropertyGraph.DeleteParts(elementsToDelete.Select(x => x.UIElementDesign), out mapping); var operation = new DeletedPartsTrackingOperation <UIElementDesign, UIElement>(asset, mapping); UndoRedoService.PushOperation(operation); UndoRedoService.SetName(transaction, "Delete selected UI elements"); } // Clear active root if it was deleted if (hadActiveRoot) { ActiveRoot = null; } }
private void RemoveSelectedLinks() { using (var transaction = UndoRedoService.CreateTransaction()) { var toRemove = SelectedRendererLinks.Cast <GraphicsCompositorLinkViewModel>().ToList(); // Clear selection first, so we don't try to unselect items that don't exist anymore later. SelectedRendererLinks.Clear(); foreach (var viewModel in toRemove) { viewModel.SourceSlot.ClearLink(); viewModel.Destroy(); viewModel.SourceSlot.Links.Remove(viewModel); viewModel.TargetSlot.Links.Remove(viewModel); } UndoRedoService.SetName(transaction, "Delete link(s)"); } }
public void AddDependency(PackageViewModel packageViewModel) { using (var transaction = UndoRedoService.CreateTransaction()) { DependencyRange dependency; if (packageViewModel.Package.Container is SolutionProject project) { dependency = new DependencyRange(packageViewModel.Name, new PackageVersionRange(packageViewModel.Package.Meta.Version, true), DependencyType.Project) { MSBuildProject = project.FullPath, }; } else { dependency = new DependencyRange(packageViewModel.Name, new PackageVersionRange(packageViewModel.Package.Meta.Version, true), DependencyType.Package); } var reference = new DirectDependencyReferenceViewModel(dependency, this, Dependencies, true); UndoRedoService.SetName(transaction, $"Add dependency to package '{reference.Name}'"); } }