Browse Source

Added possibility to save document as .pixi file format

flabbet 5 years ago
parent
commit
1247b6629f

+ 1 - 0
PixiEditor/Helpers/NotifyableObject.cs

@@ -6,6 +6,7 @@ namespace PixiEditor.Helpers
     [Serializable]
     [Serializable]
     public class NotifyableObject : INotifyPropertyChanged
     public class NotifyableObject : INotifyPropertyChanged
     {
     {
+        [field: NonSerialized]
         public event PropertyChangedEventHandler PropertyChanged = delegate { };
         public event PropertyChangedEventHandler PropertyChanged = delegate { };
 
 
         protected void RaisePropertyChanged(string property)
         protected void RaisePropertyChanged(string property)

+ 3 - 0
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.Events;
 using PixiEditor.Models.Images;
 using PixiEditor.Models.Images;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
@@ -48,6 +49,7 @@ namespace PixiEditor.Models.Controllers
         public int ToolSize => SelectedTool.Toolbar.GetSetting("ToolSize") != null ? (int)SelectedTool.Toolbar.GetSetting("ToolSize").Value : 1;
         public int ToolSize => SelectedTool.Toolbar.GetSetting("ToolSize") != null ? (int)SelectedTool.Toolbar.GetSetting("ToolSize").Value : 1;
 
 
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
+        public event EventHandler<DocumentChangedEventArgs> DocumentChanged;
 
 
         public BitmapOperationsUtility BitmapOperations { get; set; }
         public BitmapOperationsUtility BitmapOperations { get; set; }
         public ReadonlyToolUtility ReadonlyToolUtility { get; set; }
         public ReadonlyToolUtility ReadonlyToolUtility { get; set; }
@@ -60,6 +62,7 @@ namespace PixiEditor.Models.Controllers
             {
             {
                 _activeDocument = value;
                 _activeDocument = value;
                 RaisePropertyChanged("ActiveDocument");
                 RaisePropertyChanged("ActiveDocument");
+                DocumentChanged?.Invoke(this, new DocumentChangedEventArgs(value));
             }
             }
         }
         }
 
 

+ 2 - 1
PixiEditor/Models/DataHolders/Document.cs

@@ -9,11 +9,11 @@ using System.Diagnostics;
 using System.DirectoryServices;
 using System.DirectoryServices;
 using System.Drawing.Text;
 using System.Drawing.Text;
 using System.Linq;
 using System.Linq;
+using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
 namespace PixiEditor.Models.DataHolders
 namespace PixiEditor.Models.DataHolders
 {
 {
-    [Serializable]
     public class Document : NotifyableObject
     public class Document : NotifyableObject
     {
     {
         public event EventHandler<DocumentSizeChangedEventArgs> DocumentSizeChanged;
         public event EventHandler<DocumentSizeChangedEventArgs> DocumentSizeChanged;
@@ -59,6 +59,7 @@ namespace PixiEditor.Models.DataHolders
                 RaisePropertyChanged("ActiveLayer");
                 RaisePropertyChanged("ActiveLayer");
             }
             }
         }
         }
+        public ObservableCollection<Color> Swatches { get; set; } = new ObservableCollection<Color>();
 
 
         public Document(int width, int height)
         public Document(int width, int height)
         {
         {

+ 54 - 0
PixiEditor/Models/DataHolders/SerializableDocument.cs

@@ -0,0 +1,54 @@
+using PixiEditor.Models.Images;
+using PixiEditor.Models.Layers;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using System.Text;
+using System.Windows.Media;
+
+namespace PixiEditor.Models.DataHolders
+{
+    [Serializable]
+    public class SerializableDocument
+    {
+        public int Width { get; set; }
+        public int Height { get; set; }
+        public SerializableLayer[] Layers { get; set; }
+        public Tuple<byte, byte, byte, byte>[] Swatches { get; set; }
+
+        public SerializableDocument(Document document)
+        {
+            Width = document.Width;
+            Height = document.Height;
+            Layers = document.Layers.Select(x => new SerializableLayer(x)).ToArray();
+            Swatches = document.Swatches.Select(x=> new Tuple<byte,byte,byte,byte>(x.A, x.R, x.G, x.B)).ToArray();            
+        }
+
+        public Document ToDocument()
+        {
+            Document document = new Document(Width, Height)
+            {
+                Layers = ToLayers(),
+                Swatches = new ObservableCollection<Color>(Swatches.Select(x => Color.FromArgb(x.Item1, x.Item2, x.Item3, x.Item4))),                
+            };
+            return document;
+        }
+
+        private ObservableCollection<Layer> ToLayers()
+        {
+            ObservableCollection<Layer> layers = new ObservableCollection<Layer>();
+            for (int i = 0; i < Layers.Length; i++)
+            {
+                SerializableLayer serLayer = Layers[i];
+                Layer layer = new Layer(BitmapUtils.BytesToWriteableBitmap(serLayer.Width, serLayer.Height, serLayer.BitmapBytes))
+                {
+                    IsVisible = serLayer.IsVisible,
+                    Name = serLayer.Name
+                };
+                layers.Add(layer);
+            }
+            return layers;
+        }
+    }
+}

+ 1 - 0
PixiEditor/Models/Dialogs/ImportFileDialog.cs

@@ -33,6 +33,7 @@ namespace PixiEditor.Models.Dialogs
         public override bool ShowDialog()
         public override bool ShowDialog()
         {
         {
             ImportFilePopup popup = new ImportFilePopup();
             ImportFilePopup popup = new ImportFilePopup();
+            popup.FilePath = FilePath;
             popup.ShowDialog();
             popup.ShowDialog();
             if (popup.DialogResult == true)
             if (popup.DialogResult == true)
             {
             {

+ 17 - 0
PixiEditor/Models/Events/DocumentChangedEventArgs.cs

@@ -0,0 +1,17 @@
+using PixiEditor.Models.DataHolders;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace PixiEditor.Models.Events
+{
+    public class DocumentChangedEventArgs
+    {
+        public Document NewDocument { get; set; }
+
+        public DocumentChangedEventArgs(Document newDocument)
+        {
+            NewDocument = newDocument;
+        }
+    }
+}

+ 26 - 0
PixiEditor/Models/IO/BinarySerialization.cs

@@ -0,0 +1,26 @@
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+
+namespace PixiEditor.Models.IO
+{
+    public static class BinarySerialization
+    {
+        public static void WriteToBinaryFile<T>(string path, T objectToWrite)
+        {
+            using (Stream stream = File.Open(path, FileMode.Create))
+            {
+                BinaryFormatter binaryFormatter = new BinaryFormatter();
+                binaryFormatter.Serialize(stream, objectToWrite);
+            }
+        }
+
+        public static T ReadFromBinaryFile<T>(string path)
+        {
+            using (Stream stream = File.Open(path, FileMode.Open))
+            {
+                BinaryFormatter formatter = new BinaryFormatter();
+                return (T)formatter.Deserialize(stream);
+            }
+        }
+    }
+}

+ 27 - 20
PixiEditor/Models/IO/Exporter.cs

@@ -1,4 +1,6 @@
-using PixiEditor.Models.Dialogs;
+using Microsoft.Win32;
+using PixiEditor.Models.DataHolders;
+using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
 using System;
 using System;
 using System.IO;
 using System.IO;
@@ -9,15 +11,37 @@ namespace PixiEditor.Models.IO
 {
 {
     public class Exporter
     public class Exporter
     {
     {
-        public static string SavePath = null;
+        public static string SaveDocumentPath { get; set; } = null;
         public static Size FileDimensions;
         public static Size FileDimensions;
 
 
+        public static void SaveAsNewEditableFile(Document document, bool updateWorkspacePath = false)
+        {
+            SaveFileDialog dialog = new SaveFileDialog
+            {
+                Filter = "PixiEditor Files | *.pixi",
+                DefaultExt = "pixi"
+            };
+            if ((bool)dialog.ShowDialog())
+            {
+                SaveAsEditableFile(document, dialog.FileName, updateWorkspacePath);
+            }
+        }
+
+        public static void SaveAsEditableFile(Document document, string path, bool updateWorkspacePath = false)
+        {
+
+            BinarySerialization.WriteToBinaryFile(path, new SerializableDocument(document));
+
+            if (updateWorkspacePath)
+                SaveDocumentPath = path;
+        }
+
         /// <summary>
         /// <summary>
         /// Creates ExportFileDialog to get width, height and path of file.
         /// Creates ExportFileDialog to get width, height and path of file.
         /// </summary>
         /// </summary>
         /// <param name="type">Type of file to be saved in.</param>
         /// <param name="type">Type of file to be saved in.</param>
         /// <param name="bitmap">Bitmap to be saved as file.</param>
         /// <param name="bitmap">Bitmap to be saved as file.</param>
-        public static void Export(FileType type, WriteableBitmap bitmap, Size fileDimensions)
+        public static void Export(WriteableBitmap bitmap, Size fileDimensions)
         {
         {
             ExportFileDialog info = new ExportFileDialog(fileDimensions);
             ExportFileDialog info = new ExportFileDialog(fileDimensions);
             //If OK on dialog has been clicked
             //If OK on dialog has been clicked
@@ -30,28 +54,11 @@ namespace PixiEditor.Models.IO
                     return;
                     return;
                 }
                 }
 
 
-                SavePath = info.FilePath;
                 FileDimensions = new Size(info.FileWidth, info.FileHeight);
                 FileDimensions = new Size(info.FileWidth, info.FileHeight);
                 SaveAsPng(info.FilePath, info.FileHeight, info.FileWidth, bitmap);
                 SaveAsPng(info.FilePath, info.FileHeight, info.FileWidth, bitmap);
             }
             }
         }
         }
 
 
-        /// <summary>
-        /// Saves file with info that has been recieved from ExportFileDialog before, doesn't work without before Export() usage.
-        /// </summary>
-        /// <param name="type">Type of file</param>
-        /// <param name="bitmap">Image to be saved as file.</param>
-        public static void ExportWithoutDialog(FileType type, WriteableBitmap bitmap)
-        {
-            try
-            {
-                SaveAsPng(SavePath, (int)FileDimensions.Height, (int)FileDimensions.Width, bitmap);
-            }
-            catch (Exception ex)
-            {
-                MessageBox.Show(ex.Message);
-            }
-        }
         /// <summary>
         /// <summary>
         /// Saves image to PNG file
         /// Saves image to PNG file
         /// </summary>
         /// </summary>

+ 6 - 0
PixiEditor/Models/IO/Importer.cs

@@ -1,4 +1,5 @@
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
+using PixiEditor.Models.DataHolders;
 using System;
 using System;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
@@ -25,5 +26,10 @@ namespace PixiEditor.Models.IO
             wbmp = wbmp.Resize(width, height, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
             wbmp = wbmp.Resize(width, height, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
             return wbmp;
             return wbmp;
         }
         }
+
+        public static Document ImportDocument(string path)
+        {
+            return BinarySerialization.ReadFromBinaryFile<SerializableDocument>(path).ToDocument();
+        }
     }
     }
 }
 }

+ 3 - 1
PixiEditor/Models/Layers/Layer.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Models.Tools;
+using PixiEditor.Models.Images;
+using PixiEditor.Models.Tools;
 using System;
 using System;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
@@ -7,6 +8,7 @@ namespace PixiEditor.Models.Layers
     public class Layer : BasicLayer
     public class Layer : BasicLayer
     {
     {
         private WriteableBitmap _layerBitmap;
         private WriteableBitmap _layerBitmap;
+
         private string _name;
         private string _name;
 
 
         public string Name
         public string Name

+ 26 - 0
PixiEditor/Models/Layers/SerializableLayer.cs

@@ -0,0 +1,26 @@
+using PixiEditor.Models.Layers;
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace PixiEditor.Models.DataHolders
+{
+    [Serializable]
+    public class SerializableLayer
+    {
+        public string Name { get; set; }
+        public int Width { get; set; }
+        public int Height { get; set; }
+        public byte[] BitmapBytes { get; set; }
+        public bool IsVisible { get; set; }
+
+        public SerializableLayer(Layer layer)
+        {
+            Name = layer.Name;
+            Width = layer.Width;
+            Height = layer.Height;
+            BitmapBytes = layer.ConvertBitmapToBytes();
+            IsVisible = layer.IsVisible;
+        }
+    }
+}

+ 22 - 7
PixiEditor/ViewModels/ImportFilePopupViewModel.cs

@@ -1,6 +1,7 @@
 using Microsoft.Win32;
 using Microsoft.Win32;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using System;
 using System;
+using System.IO;
 using System.Windows;
 using System.Windows;
 using System.Windows.Media.Imaging;
 using System.Windows.Media.Imaging;
 
 
@@ -38,7 +39,13 @@ namespace PixiEditor.ViewModels
         public string FilePath
         public string FilePath
         {
         {
             get { return _filePath; }
             get { return _filePath; }
-            set { if (_filePath != value) { _filePath = value; RaisePropertyChanged("FilePath"); } }
+            set { if (_filePath != value) 
+                {
+                    _filePath = value;
+                    CheckForPath(value);
+                    RaisePropertyChanged("FilePath"); 
+                } 
+            }
         }
         }
 
 
 
 
@@ -83,12 +90,7 @@ namespace PixiEditor.ViewModels
             {
             {
                 if (string.IsNullOrEmpty(path.FileName) == false)
                 if (string.IsNullOrEmpty(path.FileName) == false)
                 {
                 {
-                    PathButtonBorder = "#b8f080";
-                    PathIsCorrect = true;
-                    FilePath = path.FileName;
-                    BitmapImage bitmap = new BitmapImage(new Uri(path.FileName));
-                    ImportHeight = (int)bitmap.Height;
-                    ImportWidth = (int)bitmap.Width;
+                    CheckForPath(path.FileName);
                 }
                 }
                 else
                 else
                 {
                 {
@@ -98,6 +100,19 @@ namespace PixiEditor.ViewModels
             }
             }
         }
         }
 
 
+        private void CheckForPath(string path)
+        {
+            if(File.Exists(path) && (path.EndsWith(".png") || path.EndsWith(".jpeg") || path.EndsWith(".jpg")))
+            {
+                PathButtonBorder = "#b8f080";
+                PathIsCorrect = true;
+                _filePath = path;
+                BitmapImage bitmap = new BitmapImage(new Uri(path));
+                ImportHeight = (int)bitmap.Height;
+                ImportWidth = (int)bitmap.Width;
+            }
+        }
+
         private void CloseWindow(object parameter)
         private void CloseWindow(object parameter)
         {
         {
             ((Window)parameter).DialogResult = false;
             ((Window)parameter).DialogResult = false;

+ 2 - 2
PixiEditor/ViewModels/SaveFilePopupViewModel.cs

@@ -56,8 +56,8 @@ namespace PixiEditor.ViewModels
             {
             {
                 Title = "Export path",
                 Title = "Export path",
                 CheckPathExists = true,
                 CheckPathExists = true,
-                DefaultExt = "PNG Image (.png)|*.png",
-                Filter = "PNG Image (.png)|*.png"
+                DefaultExt = "PNG Image (.png) | *.png",
+                Filter = "PNG Image (.png) | *.png"
             };
             };
             if (path.ShowDialog() == true)
             if (path.ShowDialog() == true)
             {
             {

+ 69 - 22
PixiEditor/ViewModels/ViewModelMain.cs

@@ -1,4 +1,5 @@
-using PixiEditor.Helpers;
+using Microsoft.Win32;
+using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.Dialogs;
@@ -12,6 +13,7 @@ using PixiEditor.Models.Tools.Tools;
 using System;
 using System;
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Security.Cryptography.X509Certificates;
 using System.Security.Cryptography.X509Certificates;
 using System.Windows;
 using System.Windows;
@@ -53,6 +55,7 @@ namespace PixiEditor.ViewModels
         public RelayCommand OpenResizePopupCommand { get; set; }
         public RelayCommand OpenResizePopupCommand { get; set; }
         public RelayCommand SelectColorCommand { get; set; }
         public RelayCommand SelectColorCommand { get; set; }
         public RelayCommand RemoveSwatchCommand { get; set; }
         public RelayCommand RemoveSwatchCommand { get; set; }
+        public RelayCommand SaveDocumentCommand { get; set; }
 
 
 
 
         private double _mouseXonCanvas;
         private double _mouseXonCanvas;
@@ -121,7 +124,6 @@ namespace PixiEditor.ViewModels
         }
         }
 
 
         public ObservableCollection<Tool> ToolSet { get; set; }
         public ObservableCollection<Tool> ToolSet { get; set; }
-        public ObservableCollection<Color> Swatches { get; set; } = new ObservableCollection<Color>();
 
 
         private LayerChange[] _undoChanges;
         private LayerChange[] _undoChanges;
 
 
@@ -175,6 +177,7 @@ namespace PixiEditor.ViewModels
             BitmapManager = new BitmapManager();
             BitmapManager = new BitmapManager();
             BitmapManager.BitmapOperations.BitmapChanged += BitmapUtility_BitmapChanged;
             BitmapManager.BitmapOperations.BitmapChanged += BitmapUtility_BitmapChanged;
             BitmapManager.MouseController.StoppedRecordingChanges += MouseController_StoppedRecordingChanges;
             BitmapManager.MouseController.StoppedRecordingChanges += MouseController_StoppedRecordingChanges;
+            BitmapManager.DocumentChanged += BitmapManager_DocumentChanged;
             ChangesController = new PixelChangesController();
             ChangesController = new PixelChangesController();
             SelectToolCommand = new RelayCommand(SetTool, DocumentIsNotNull);
             SelectToolCommand = new RelayCommand(SetTool, DocumentIsNotNull);
             OpenNewFilePopupCommand = new RelayCommand(OpenNewFilePopup);
             OpenNewFilePopupCommand = new RelayCommand(OpenNewFilePopup);
@@ -184,7 +187,7 @@ namespace PixiEditor.ViewModels
             UndoCommand = new RelayCommand(Undo, CanUndo);
             UndoCommand = new RelayCommand(Undo, CanUndo);
             RedoCommand = new RelayCommand(Redo, CanRedo);
             RedoCommand = new RelayCommand(Redo, CanRedo);
             MouseUpCommand = new RelayCommand(MouseUp);
             MouseUpCommand = new RelayCommand(MouseUp);
-            OpenFileCommand = new RelayCommand(OpenFile);
+            OpenFileCommand = new RelayCommand(Open);
             SetActiveLayerCommand = new RelayCommand(SetActiveLayer);
             SetActiveLayerCommand = new RelayCommand(SetActiveLayer);
             NewLayerCommand = new RelayCommand(NewLayer, CanCreateNewLayer);
             NewLayerCommand = new RelayCommand(NewLayer, CanCreateNewLayer);
             DeleteLayerCommand = new RelayCommand(DeleteLayer, CanDeleteLayer);
             DeleteLayerCommand = new RelayCommand(DeleteLayer, CanDeleteLayer);
@@ -204,6 +207,7 @@ namespace PixiEditor.ViewModels
             OpenResizePopupCommand = new RelayCommand(OpenResizePopup, DocumentIsNotNull);
             OpenResizePopupCommand = new RelayCommand(OpenResizePopup, DocumentIsNotNull);
             SelectColorCommand = new RelayCommand(SelectColor);
             SelectColorCommand = new RelayCommand(SelectColor);
             RemoveSwatchCommand = new RelayCommand(RemoveSwatch);
             RemoveSwatchCommand = new RelayCommand(RemoveSwatch);
+            SaveDocumentCommand = new RelayCommand(SaveDocument, 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()};            
             ShortcutController = new ShortcutController
             ShortcutController = new ShortcutController
@@ -223,9 +227,10 @@ namespace PixiEditor.ViewModels
                     new Shortcut(Key.M, SelectToolCommand, ToolType.Select),
                     new Shortcut(Key.M, SelectToolCommand, ToolType.Select),
                     new Shortcut(Key.Y, RedoCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.Y, RedoCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.Z, UndoCommand),
                     new Shortcut(Key.Z, UndoCommand),
-                    new Shortcut(Key.S, SaveFileCommand, modifier: ModifierKeys.Control),
+                    new Shortcut(Key.S, SaveFileCommand, modifier: ModifierKeys.Control | ModifierKeys.Shift | ModifierKeys.Alt),
+                    new Shortcut(Key.S, SaveDocumentCommand, modifier: ModifierKeys.Control),
+                    new Shortcut(Key.S, SaveDocumentCommand, "AsNew", modifier: ModifierKeys.Control | ModifierKeys.Shift),
                     new Shortcut(Key.N, OpenNewFilePopupCommand, modifier: ModifierKeys.Control),
                     new Shortcut(Key.N, OpenNewFilePopupCommand, modifier: ModifierKeys.Control),
-                    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),
@@ -244,6 +249,51 @@ namespace PixiEditor.ViewModels
             Current = this;
             Current = this;
         }
         }
 
 
+        private void BitmapManager_DocumentChanged(object sender, Models.Events.DocumentChangedEventArgs e)
+        {
+            e.NewDocument.DocumentSizeChanged += ActiveDocument_DocumentSizeChanged;
+        }
+
+        private void Open(object property)
+        {
+            OpenFileDialog dialog = new OpenFileDialog
+            {
+                Filter = "All Files|*.*|PixiEditor Files | *.pixi|PNG Files|*.png",
+                DefaultExt = "pixi"
+            };
+            if ((bool)dialog.ShowDialog())
+            {
+                if (dialog.FileName.EndsWith(".png") || dialog.FileName.EndsWith(".jpeg") || dialog.FileName.EndsWith(".jpg"))
+                {
+                    OpenFile(dialog.FileName);
+                }
+                else if (dialog.FileName.EndsWith(".pixi"))
+                {
+                    OpenDocument(dialog.FileName);
+                }
+                RecenterZoombox = !RecenterZoombox;
+            }
+        }
+
+        private void OpenDocument(string path)
+        {
+            BitmapManager.ActiveDocument = Importer.ImportDocument(path);
+            Exporter.SaveDocumentPath = path;
+        }
+
+        private void SaveDocument(object parameter)
+        {
+            bool paramIsAsNew = parameter != null && parameter.ToString().ToLower() == "asnew";
+            if (paramIsAsNew || Exporter.SaveDocumentPath == null)
+            {
+                Exporter.SaveAsNewEditableFile(BitmapManager.ActiveDocument, !paramIsAsNew);
+            }
+            else
+            {
+                Exporter.SaveAsEditableFile(BitmapManager.ActiveDocument, Exporter.SaveDocumentPath);
+            }
+        }
+
         private void RemoveSwatch(object parameter)
         private void RemoveSwatch(object parameter)
         {
         {
             if (!(parameter is Color))
             if (!(parameter is Color))
@@ -251,9 +301,9 @@ namespace PixiEditor.ViewModels
                 throw new ArgumentException();
                 throw new ArgumentException();
             }
             }
             Color color = (Color)parameter;
             Color color = (Color)parameter;
-            if (Swatches.Contains(color)) 
+            if (BitmapManager.ActiveDocument.Swatches.Contains(color)) 
             {
             {
-                Swatches.Remove(color);
+                BitmapManager.ActiveDocument.Swatches.Remove(color);
             }
             }
         }
         }
 
 
@@ -274,9 +324,9 @@ namespace PixiEditor.ViewModels
 
 
         public void AddSwatch(Color color)
         public void AddSwatch(Color color)
         {
         {
-            if (!Swatches.Contains(color))
+            if (!BitmapManager.ActiveDocument.Swatches.Contains(color))
             {
             {
-                Swatches.Add(color);
+                BitmapManager.ActiveDocument.Swatches.Add(color);
             }
             }
         }
         }
 
 
@@ -581,14 +631,7 @@ namespace PixiEditor.ViewModels
         private void SaveFile(object parameter)
         private void SaveFile(object parameter)
         {
         {
             WriteableBitmap bitmap = BitmapManager.GetCombinedLayersBitmap();
             WriteableBitmap bitmap = BitmapManager.GetCombinedLayersBitmap();
-            if (Exporter.SavePath == null || (string)parameter == "AsNew")
-            {
-                Exporter.Export(FileType.PNG, bitmap, new Size(bitmap.PixelWidth, bitmap.PixelHeight));
-            }
-            else
-            {
-                Exporter.ExportWithoutDialog(FileType.PNG, bitmap);
-            }
+            Exporter.Export(bitmap, new Size(bitmap.PixelWidth, bitmap.PixelHeight));
         }
         }
         /// <summary>
         /// <summary>
         /// Returns true if file save is possible.
         /// Returns true if file save is possible.
@@ -604,10 +647,14 @@ namespace PixiEditor.ViewModels
         /// <summary>
         /// <summary>
         /// Opens file from path.
         /// Opens file from path.
         /// </summary>
         /// </summary>
-        /// <param name="parameter"></param>
-        public void OpenFile(object parameter)
+        /// <param name="path"></param>
+        public void OpenFile(string path)
         {
         {
-            ImportFileDialog dialog = new ImportFileDialog();
+            ImportFileDialog dialog = new ImportFileDialog();
+
+            if (path != null && File.Exists(path.ToString()))
+                dialog.FilePath = path.ToString();
+
             if (dialog.ShowDialog())
             if (dialog.ShowDialog())
             {
             {
                 NewDocument(dialog.FileWidth, dialog.FileHeight);
                 NewDocument(dialog.FileWidth, dialog.FileHeight);
@@ -617,13 +664,13 @@ namespace PixiEditor.ViewModels
 
 
         private void NewDocument(int width, int height)
         private void NewDocument(int width, int height)
         {
         {
-            BitmapManager.ActiveDocument = new Models.DataHolders.Document(width, height);
+            BitmapManager.ActiveDocument = new Document(width, height);
             BitmapManager.AddNewLayer("Base Layer", width, height, true);
             BitmapManager.AddNewLayer("Base Layer", width, height, true);
             BitmapManager.PreviewLayer = null;
             BitmapManager.PreviewLayer = null;
             UndoManager.UndoStack.Clear();
             UndoManager.UndoStack.Clear();
             UndoManager.RedoStack.Clear();
             UndoManager.RedoStack.Clear();
             ActiveSelection = new Selection(Array.Empty<Coordinates>());
             ActiveSelection = new Selection(Array.Empty<Coordinates>());
-            BitmapManager.ActiveDocument.DocumentSizeChanged += ActiveDocument_DocumentSizeChanged;
+            RecenterZoombox = !RecenterZoombox;
         }
         }
 
 
         public void NewLayer(object parameter)
         public void NewLayer(object parameter)

+ 0 - 1
PixiEditor/Views/ImportFilePopup.xaml.cs

@@ -36,7 +36,6 @@ namespace PixiEditor.Views
         }
         }
 
 
 
 
-
         public string FilePath
         public string FilePath
         {
         {
             get { return dc.FilePath; }
             get { return dc.FilePath; }

+ 4 - 3
PixiEditor/Views/MainWindow.xaml

@@ -64,8 +64,9 @@
                 <MenuItem Header="_File">
                 <MenuItem Header="_File">
                     <MenuItem InputGestureText="CTRL+N" Header="_New" Command="{Binding OpenNewFilePopupCommand}"/>
                     <MenuItem InputGestureText="CTRL+N" Header="_New" Command="{Binding OpenNewFilePopupCommand}"/>
                     <MenuItem Header="_Open" InputGestureText="Ctrl+O" Command="{Binding OpenFileCommand}"/>
                     <MenuItem Header="_Open" InputGestureText="Ctrl+O" Command="{Binding OpenFileCommand}"/>
-                    <MenuItem Header="_Export" InputGestureText="Ctrl+S" Command="{Binding SaveFileCommand}"/>
-                    <MenuItem Header="_Export As..." InputGestureText="Ctrl+Shift+S" Command="{Binding SaveFileCommand}" CommandParameter="AsNew"/>
+                    <MenuItem Header="_Save" InputGestureText="Ctrl+S" Command="{Binding SaveDocumentCommand}"/>
+                    <MenuItem Header="_Save As..." InputGestureText="Ctrl+Shift+S" Command="{Binding SaveDocumentCommand}"/>
+                    <MenuItem Header="_Export" InputGestureText="Ctrl+Shift+Alt+S" Command="{Binding SaveFileCommand}"/>
                 </MenuItem>
                 </MenuItem>
                 <MenuItem Header="_Edit">
                 <MenuItem Header="_Edit">
                     <MenuItem Header="_Undo" InputGestureText="Ctrl+Z" Command="{Binding UndoCommand}"/>
                     <MenuItem Header="_Undo" InputGestureText="Ctrl+Z" Command="{Binding UndoCommand}"/>
@@ -243,7 +244,7 @@
                         <avalondock:LayoutAnchorablePane>
                         <avalondock:LayoutAnchorablePane>
                             <avalondock:LayoutAnchorable ContentId="swatches" Title="Swatches" CanHide="False" CanClose="False" CanAutoHide="False" CanDockAsTabbedDocument="False" CanFloat="True">
                             <avalondock:LayoutAnchorable ContentId="swatches" Title="Swatches" CanHide="False" CanClose="False" CanAutoHide="False" CanDockAsTabbedDocument="False" CanFloat="True">
                                 <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
                                 <ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto">
-                                    <ItemsControl ItemsSource="{Binding Swatches}">
+                                    <ItemsControl ItemsSource="{Binding BitmapManager.ActiveDocument.Swatches}">
                                         <ItemsControl.ItemsPanel>
                                         <ItemsControl.ItemsPanel>
                                             <ItemsPanelTemplate>
                                             <ItemsPanelTemplate>
                                                 <WrapPanel Margin="10,0,0,0" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left"/>
                                                 <WrapPanel Margin="10,0,0,0" Orientation="Horizontal" VerticalAlignment="Top" HorizontalAlignment="Left"/>