Browse Source

Added paste from clipboard

flabbet 5 years ago
parent
commit
b1f2c9105e

+ 2 - 18
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -1,6 +1,7 @@
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
+using PixiEditor.Models.Images;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Tools;
 using PixiEditor.Models.Tools;
@@ -184,24 +185,7 @@ namespace PixiEditor.Models.Controllers
 
 
         public WriteableBitmap GetCombinedLayersBitmap()
         public WriteableBitmap GetCombinedLayersBitmap()
         {
         {
-            WriteableBitmap finalBitmap = ActiveDocument.Layers[0].LayerBitmap.Clone();
-            finalBitmap.Lock();
-            for (int i = 1; i < ActiveDocument.Layers.Count; i++)
-            {
-                for (int y = 0; y < finalBitmap.Height; y++)
-                {
-                    for (int x = 0; x < finalBitmap.Width; x++)
-                    {
-                        Color color = ActiveDocument.Layers[i].LayerBitmap.GetPixel(x, y);
-                        if (color.A != 0 || color.R != 0 || color.B != 0 || color.G != 0)
-                        {
-                            finalBitmap.SetPixel(x, y, color);
-                        }
-                    }
-                }
-            }
-            finalBitmap.Unlock();
-            return finalBitmap;
+            return BitmapUtils.CombineBitmaps(ActiveDocument.Layers.ToArray());
         }
         }
 
 
 
 

+ 54 - 8
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -1,5 +1,10 @@
-using PixiEditor.Models.Position;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Images;
+using PixiEditor.Models.Layers;
+using PixiEditor.Models.Position;
+using PixiEditor.ViewModels;
 using System;
 using System;
+using System.Drawing;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Windows;
 using System.Windows;
@@ -9,13 +14,20 @@ namespace PixiEditor.Models.Controllers
 {
 {
     public class ClipboardController
     public class ClipboardController
     {
     {
-        public void CopyToClipboard(WriteableBitmap bitmap, Coordinates[] selection)
+
+        /// <summary>
+        /// Copies selection to clipboard in PNG, Bitmap and DIB formats.
+        /// </summary>
+        /// <param name="bitmap">Bitmap where selection is</param>
+        /// <param name="selection"></param>
+        public void CopyToClipboard(Layer[] layers, Coordinates[] selection)
         {
         {
             Clipboard.Clear();
             Clipboard.Clear();
+            WriteableBitmap combinedBitmaps = BitmapUtils.CombineBitmaps(layers);
             using (var pngStream = new MemoryStream())
             using (var pngStream = new MemoryStream())
             {
             {
                 DataObject data = new DataObject();
                 DataObject data = new DataObject();
-                var croppedBmp = BitmapSelectionToBmpSource(bitmap.Clone(), selection);
+                var croppedBmp = BitmapSelectionToBmpSource(combinedBitmaps, selection);
                 data.SetData(DataFormats.Bitmap, croppedBmp, true); //Bitmap, no transparency support
                 data.SetData(DataFormats.Bitmap, croppedBmp, true); //Bitmap, no transparency support
 
 
                 PngBitmapEncoder encoder = new PngBitmapEncoder();
                 PngBitmapEncoder encoder = new PngBitmapEncoder();
@@ -23,10 +35,49 @@ namespace PixiEditor.Models.Controllers
                 encoder.Save(pngStream);
                 encoder.Save(pngStream);
                 data.SetData("PNG", pngStream, false); //PNG, supports transparency
                 data.SetData("PNG", pngStream, false); //PNG, supports transparency
 
 
+                Clipboard.SetImage(croppedBmp); //DIB format
                 Clipboard.SetDataObject(data, true);
                 Clipboard.SetDataObject(data, true);
             }
             }
         }
         }
 
 
+        public void PasteFromClipboard()
+        {
+            DataObject dao = (DataObject)Clipboard.GetDataObject();
+            WriteableBitmap finalImage = null;
+            if (dao.GetDataPresent("PNG"))
+            {
+                using (MemoryStream pngStream = dao.GetData("PNG") as MemoryStream)
+                {
+                    if (pngStream != null)
+                    {
+                        PngBitmapDecoder decoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.OnLoad);
+                        finalImage = new WriteableBitmap(decoder.Frames[0].Clone());
+                    }
+                }
+            }
+            else if (dao.GetDataPresent(DataFormats.Dib))
+            {
+                finalImage = new WriteableBitmap(Clipboard.GetImage());
+            }
+            else if (dao.GetDataPresent(DataFormats.Bitmap))
+            {
+                finalImage = new WriteableBitmap(dao.GetData(DataFormats.Bitmap) as BitmapSource);
+            }
+            if (finalImage != null)
+            {
+                AddImageToLayers(finalImage);
+            }
+        }
+
+        private void AddImageToLayers(WriteableBitmap image)
+        {
+            Document doc = ViewModelMain.Current.BitmapManager.ActiveDocument;
+            Rect imgRect = new Rect(0, 0, image.PixelWidth, image.PixelHeight);
+            ViewModelMain.Current.BitmapManager.AddNewLayer("Image", doc.Width, doc.Height, true);
+            ViewModelMain.Current.BitmapManager.ActiveLayer.
+                LayerBitmap.Blit(imgRect, image, imgRect);
+        }
+
         public BitmapSource BitmapSelectionToBmpSource(WriteableBitmap bitmap, Coordinates[] selection)
         public BitmapSource BitmapSelectionToBmpSource(WriteableBitmap bitmap, Coordinates[] selection)
         {
         {
             int offsetX = selection.Min(x => x.X);
             int offsetX = selection.Min(x => x.X);
@@ -35,10 +86,5 @@ namespace PixiEditor.Models.Controllers
             int height = selection.Max(x => x.Y) - offsetY + 1;
             int height = selection.Max(x => x.Y) - offsetY + 1;
             return bitmap.Crop(offsetX, offsetY, width, height);
             return bitmap.Crop(offsetX, offsetY, width, height);
         }
         }
-
-        public WriteableBitmap GetFromClipboard()
-        {
-            throw new NotImplementedException();
-        }
     }
     }
 }
 }

+ 0 - 14
PixiEditor/Models/Images/BitmapConverter.cs

@@ -1,14 +0,0 @@
-using System.Windows.Media.Imaging;
-
-namespace PixiEditor.Models.Images
-{
-    public static class BitmapConverter
-    {
-        public static WriteableBitmap BytesToWriteableBitmap(int currentBitmapWidth, int currentBitmapHeight, byte[] byteArray)
-        {
-            WriteableBitmap bitmap = BitmapFactory.New(currentBitmapWidth, currentBitmapHeight);
-            bitmap.FromByteArray(byteArray);
-            return bitmap;
-        }
-    }
-}

+ 56 - 0
PixiEditor/Models/Images/BitmapUtils.cs

@@ -0,0 +1,56 @@
+using PixiEditor.Models.Layers;
+using System;
+using System.Drawing;
+using System.Linq;
+using System.Windows;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace PixiEditor.Models.Images
+{
+    public static class BitmapUtils
+    {
+        public static WriteableBitmap BytesToWriteableBitmap(int currentBitmapWidth, int currentBitmapHeight, byte[] byteArray)
+        {
+            WriteableBitmap bitmap = BitmapFactory.New(currentBitmapWidth, currentBitmapHeight);
+            bitmap.FromByteArray(byteArray);
+            return bitmap;
+        }
+
+        public static BitmapSource BitmapToBitmapSource(Bitmap bitmap)
+        {
+            return System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
+                  bitmap.GetHbitmap(),
+                  IntPtr.Zero,
+                  Int32Rect.Empty,
+                  BitmapSizeOptions.FromEmptyOptions());
+        }
+
+        public static WriteableBitmap CombineBitmaps(Layer[] layers)
+        {
+            return CombineBitmaps(layers.Select(x => x.LayerBitmap).ToArray());
+        }
+
+        public static WriteableBitmap CombineBitmaps(WriteableBitmap[] bitmaps)
+        {
+            WriteableBitmap finalBitmap = bitmaps[0].Clone();
+            finalBitmap.Lock();
+            for (int i = 1; i < bitmaps.Length; i++)
+            {
+                for (int y = 0; y < finalBitmap.Height; y++)
+                {
+                    for (int x = 0; x < finalBitmap.Width; x++)
+                    {
+                        System.Windows.Media.Color color = bitmaps[i].GetPixel(x, y);
+                        if (color.A != 0 || color.R != 0 || color.B != 0 || color.G != 0)
+                        {
+                            finalBitmap.SetPixel(x, y, color);
+                        }
+                    }
+                }
+            }
+            finalBitmap.Unlock();
+            return finalBitmap;
+        }
+    }
+}

+ 2 - 2
PixiEditor/Models/Tools/Tools/MoveTool.cs

@@ -33,7 +33,7 @@ namespace PixiEditor.Models.Tools.Tools
             Coordinates start = mouseMove[^1];
             Coordinates start = mouseMove[^1];
             if (_lastStartMousePos != start)
             if (_lastStartMousePos != start)
             {
             {
-                ResetSelectionValues(layer, start);
+                ResetSelectionValues(start);
                 if (ViewModelMain.Current.ActiveSelection.SelectedPoints == null) //Move every pixel if none is selected
                 if (ViewModelMain.Current.ActiveSelection.SelectedPoints == null) //Move every pixel if none is selected
                 {
                 {
                     SelectTool select = new SelectTool();
                     SelectTool select = new SelectTool();
@@ -68,7 +68,7 @@ namespace PixiEditor.Models.Tools.Tools
                         _currentSelection, _startPixelColors);
                         _currentSelection, _startPixelColors);
         }
         }
 
 
-        private void ResetSelectionValues(Layer layer, Coordinates start)
+        private void ResetSelectionValues(Coordinates start)
         {
         {
             _lastStartMousePos = start;
             _lastStartMousePos = start;
             _lastMouseMove = start;
             _lastMouseMove = start;

+ 10 - 2
PixiEditor/ViewModels/ViewModelMain.cs

@@ -43,6 +43,7 @@ namespace PixiEditor.ViewModels
         public RelayCommand DeselectCommand { get; set; }
         public RelayCommand DeselectCommand { get; set; }
         public RelayCommand SelectAllCommand { get; set; }
         public RelayCommand SelectAllCommand { get; set; }
         public RelayCommand CopyCommand { get; set; }
         public RelayCommand CopyCommand { get; set; }
+        public RelayCommand PasteCommand { get; set; }
         public RelayCommand ClipCanvasCommand { get; set; }
         public RelayCommand ClipCanvasCommand { get; set; }
 
 
 
 
@@ -175,6 +176,7 @@ namespace PixiEditor.ViewModels
             DeselectCommand = new RelayCommand(Deselect, SelectionIsNotEmpty);
             DeselectCommand = new RelayCommand(Deselect, SelectionIsNotEmpty);
             SelectAllCommand = new RelayCommand(SelectAll, CanSelectAll);
             SelectAllCommand = new RelayCommand(SelectAll, CanSelectAll);
             CopyCommand = new RelayCommand(Copy, SelectionIsNotEmpty);
             CopyCommand = new RelayCommand(Copy, SelectionIsNotEmpty);
+            PasteCommand = new RelayCommand(Paste);
             ClipCanvasCommand = new RelayCommand(ClipCanvas, DocumentIsNotNull);
             ClipCanvasCommand = new RelayCommand(ClipCanvas, DocumentIsNotNull);
             ToolSet = new ObservableCollection<Tool> {new MoveTool(), new PenTool(), new SelectTool(), new FloodFill(), new LineTool(),
             ToolSet = new ObservableCollection<Tool> {new MoveTool(), new PenTool(), new SelectTool(), new FloodFill(), new LineTool(),
             new CircleTool(), new RectangleTool(), new EarserTool(), new ColorPickerTool(), new BrightnessTool()};
             new CircleTool(), new RectangleTool(), new EarserTool(), new ColorPickerTool(), new BrightnessTool()};
@@ -198,7 +200,8 @@ namespace PixiEditor.ViewModels
                     new Shortcut(Key.S, SaveFileCommand, "AsNew", ModifierKeys.Control | ModifierKeys.Shift),
                     new Shortcut(Key.S, SaveFileCommand, "AsNew", ModifierKeys.Control | ModifierKeys.Shift),
                     new Shortcut(Key.D, DeselectCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.D, DeselectCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.A, SelectAllCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.A, SelectAllCommand, modifier: ModifierKeys.Control),
-                    new Shortcut(Key.C, CopyCommand, modifier: ModifierKeys.Control)
+                    new Shortcut(Key.C, CopyCommand, modifier: ModifierKeys.Control),
+                    new Shortcut(Key.V, PasteCommand, modifier: ModifierKeys.Control)
                 }
                 }
             };
             };
             UndoManager.SetMainRoot(this);
             UndoManager.SetMainRoot(this);
@@ -214,9 +217,14 @@ namespace PixiEditor.ViewModels
                 BitmapManager.ActiveDocument.ClipCanvas();
                 BitmapManager.ActiveDocument.ClipCanvas();
         }
         }
 
 
+        public void Paste(object parameter)
+        {
+            ClipboardController.PasteFromClipboard();
+        }
+
         private void Copy(object parameter)
         private void Copy(object parameter)
         {
         {
-            ClipboardController.CopyToClipboard(BitmapManager.ActiveLayer.LayerBitmap, ActiveSelection.SelectedPoints);
+            ClipboardController.CopyToClipboard(BitmapManager.ActiveDocument.Layers.ToArray(), ActiveSelection.SelectedPoints);
         }
         }
 
 
         public void SelectAll(object parameter)
         public void SelectAll(object parameter)

+ 1 - 1
PixiEditor/Views/MainWindow.xaml

@@ -71,7 +71,7 @@
                     <MenuItem Header="_Redo" InputGestureText="Ctrl+Y" Command="{Binding RedoCommand}"/>
                     <MenuItem Header="_Redo" InputGestureText="Ctrl+Y" Command="{Binding RedoCommand}"/>
                     <Separator/>
                     <Separator/>
                     <MenuItem Header="_Copy" Command="{Binding CopyCommand}" InputGestureText="Ctrl+C"/>
                     <MenuItem Header="_Copy" Command="{Binding CopyCommand}" InputGestureText="Ctrl+C"/>
-                    <MenuItem Header="_Paste"/>
+                    <MenuItem Header="_Paste" Command="{Binding PasteCommand}" InputGestureText="Ctrl+V"/>
                 </MenuItem>
                 </MenuItem>
                 <MenuItem Header="_Select">
                 <MenuItem Header="_Select">
                     <MenuItem Header="_Select All" Command="{Binding SelectAllCommand}" InputGestureText="Ctrl+A"/>
                     <MenuItem Header="_Select All" Command="{Binding SelectAllCommand}" InputGestureText="Ctrl+A"/>