Explorar el Código

Added place element

Krzysztof Krysiński hace 3 semanas
padre
commit
a81feb36ed

+ 4 - 1
src/PixiEditor/Data/Localization/Languages/en.json

@@ -1252,5 +1252,8 @@
   "LOCAL": "Local",
   "TOOL_CONFIG": "Tool Config",
   "FORCE_PRESSURE_SETTING": "Force Pressure",
-  "TO_SMART_LAYER": "To Smart Layer"
+  "TO_SMART_LAYER": "To Smart Layer",
+  "PLACE_ELEMENT": "Place Element",
+  "PLACE_ELEMENT_DESCRIPTIVE": "Place an external image or document as a new layer",
+  "FAILED_TO_PLACE_ELEMENT": "Failed to place element: {0}"
 }

+ 38 - 24
src/PixiEditor/Models/Controllers/ClipboardController.cs

@@ -345,33 +345,13 @@ internal static class ClipboardController
                     continue;
                 }
 
-                try
-                {
-                    DocumentViewModel importedDoc = manager.Owner.FileSubViewModel.ImportFromPath(path);
-                    if (importedDoc == null)
-                    {
-                        continue;
-                    }
-
-                    Guid? guid = document.Operations.CreateStructureMember(StructureMemberType.Document,
-                        Path.GetFileNameWithoutExtension(importedDoc.FileName));
-
-                    if (guid == null)
-                    {
-                        continue;
-                    }
-
-                    document.Operations.SetNodeInputPropertyValue(guid.Value, NestedDocumentNode.DocumentPropertyName,
-                        new DocumentReference(importedDoc.FullFilePath, importedDoc.Id,
-                            importedDoc.AccessInternalReadOnlyDocument().Clone()));
-
-                    importedDoc.Dispose();
-                    importedAny = true;
-                }
-                catch
+                bool imported = TryPlaceNestedDocument(document, manager, path, out _);
+                if(!imported)
                 {
                     continue;
                 }
+
+                importedAny = true;
             }
 
             return importedAny;
@@ -380,6 +360,40 @@ internal static class ClipboardController
         return false;
     }
 
+    public static bool TryPlaceNestedDocument(DocumentViewModel document, DocumentManagerViewModel manager, string path, out string? error)
+    {
+        try
+        {
+            DocumentViewModel importedDoc = manager.Owner.FileSubViewModel.ImportFromPath(path);
+            error = null;
+            if (importedDoc == null)
+            {
+                return false;
+            }
+
+            Guid? guid = document.Operations.CreateStructureMember(StructureMemberType.Document,
+                Path.GetFileNameWithoutExtension(importedDoc.FileName));
+
+            if (guid == null)
+            {
+                return false;
+            }
+
+            document.Operations.SetNodeInputPropertyValue(guid.Value, NestedDocumentNode.DocumentPropertyName,
+                new DocumentReference(importedDoc.FullFilePath, importedDoc.Id,
+                    importedDoc.AccessInternalReadOnlyDocument().Clone()));
+
+            importedDoc.Dispose();
+            return true;
+        }
+        catch (Exception ex)
+        {
+            error = ex.Message;
+            CrashHelper.SendExceptionInfo(ex);
+            return false;
+        }
+    }
+
     private static List<Guid> AdjustIdsForImport(Guid[] layerIds, IDocument targetDoc)
     {
         // This should only copy root level layers

+ 33 - 1
src/PixiEditor/ViewModels/SubViewModels/FileViewModel.cs

@@ -35,6 +35,7 @@ using PixiEditor.ViewModels.Document;
 using PixiEditor.Views;
 using PixiEditor.Views.Dialogs;
 using PixiEditor.Views.Windows;
+using Wasmtime;
 
 namespace PixiEditor.ViewModels.SubViewModels;
 
@@ -225,7 +226,7 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
     [Command.Basic("PixiEditor.File.OpenFileFromClipboard", "OPEN_FILE_FROM_CLIPBOARD",
         "OPEN_FILE_FROM_CLIPBOARD_DESCRIPTIVE", CanExecute = "PixiEditor.Clipboard.HasImageInClipboard",
         Icon = PixiPerfectIcons.PasteAsNewLayer,
-        MenuItemPath = "FILE/OPEN_FILE_FROM_CLIPBOARD", MenuItemOrder = 2,
+        MenuItemPath = "FILE/OPEN_FILE_FROM_CLIPBOARD", MenuItemOrder = 3,
         AnalyticsTrack = true)]
     public void OpenFromClipboard()
     {
@@ -246,6 +247,37 @@ internal class FileViewModel : SubViewModel<ViewModelMain>
         });
     }
 
+    [Command.Basic("PixiEditor.File.PlaceElement", "PLACE_ELEMENT", "PLACE_ELEMENT_DESCRIPTIVE",
+        Key = Key.M, Modifiers = KeyModifiers.Control | KeyModifiers.Shift,
+        MenuItemPath = "FILE/PLACE_ELEMENT", MenuItemOrder = 2, Icon = PixiPerfectIcons.FilePlus,
+        AnalyticsTrack = true)]
+    public void PlaceElement()
+    {
+        Dispatcher.UIThread.InvokeAsync(async () =>
+        {
+            var filter = SupportedFilesHelper.BuildOpenFilter();
+
+            if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
+            {
+                var dialog = await desktop.MainWindow.StorageProvider.OpenFilePickerAsync(
+                    new FilePickerOpenOptions { FileTypeFilter = filter });
+
+                if (dialog.Count == 0 || !Importer.IsSupportedFile(dialog[0].Path.LocalPath))
+                    return;
+
+                var manager = Owner.DocumentManagerSubViewModel;
+                if (manager.ActiveDocument is null)
+                    return;
+
+                if (!ClipboardController.TryPlaceNestedDocument(manager.ActiveDocument, manager,
+                        dialog[0].Path.LocalPath, out string? error))
+                {
+                    NoticeDialog.Show(new LocalizedString("FAILED_TO_PLACE_ELEMENT", error), "ERROR");
+                }
+            }
+        });
+    }
+
     private bool MakeExistingDocumentActiveIfOpened(string path)
     {
         foreach (DocumentViewModel document in Owner.DocumentManagerSubViewModel.Documents)