Browse Source

Fixed UndoManager, Selection and close individual documents

flabbet 4 years ago
parent
commit
d841ed1e7b

+ 13 - 0
PixiEditor/Models/Controllers/BitmapManager.cs

@@ -104,6 +104,19 @@ namespace PixiEditor.Models.Controllers
             return tool is BitmapOperationTool;
             return tool is BitmapOperationTool;
         }
         }
 
 
+        public void CloseDocument(Document document)
+        {
+            int nextIndex = 0;
+            if (document == ActiveDocument)
+            {
+                nextIndex = Documents.Count > 1 ? Documents.IndexOf(document) : -1;
+                nextIndex += nextIndex > 0 ? -1 : 0;
+            }
+
+            Documents.Remove(document);
+            ActiveDocument = nextIndex >= 0 ? Documents[nextIndex] : null;
+        }
+
         public void ExecuteTool(Coordinates newPosition, bool clickedOnCanvas)
         public void ExecuteTool(Coordinates newPosition, bool clickedOnCanvas)
         {
         {
             if (SelectedTool.CanStartOutsideCanvas || clickedOnCanvas)
             if (SelectedTool.CanStartOutsideCanvas || clickedOnCanvas)

+ 1 - 1
PixiEditor/Models/Controllers/BitmapOperationsUtility.cs

@@ -47,7 +47,7 @@ namespace PixiEditor.Models.Controllers
                 layers[i].SetPixels(changes);
                 layers[i].SetPixels(changes);
             }
             }
 
 
-            UndoManager.AddUndoChange(new Change("UndoChanges", old, newChange, "Deleted pixels"));
+            Manager.ActiveDocument.UndoManager.AddUndoChange(new Change("UndoChanges", old, newChange, "Deleted pixels"));
         }
         }
 
 
         /// <summary>
         /// <summary>

+ 1 - 1
PixiEditor/Models/Controllers/ClipboardController.cs

@@ -46,7 +46,7 @@ namespace PixiEditor.Models.Controllers
             {
             {
                 AddImageToLayers(image);
                 AddImageToLayers(image);
                 int latestLayerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Count - 1;
                 int latestLayerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.Count - 1;
-                UndoManager.AddUndoChange(
+                ViewModelMain.Current.BitmapManager.ActiveDocument.UndoManager.AddUndoChange(
                     new Change(RemoveLayerProcess, new object[] { latestLayerIndex }, AddLayerProcess, new object[] { image }));
                     new Change(RemoveLayerProcess, new object[] { latestLayerIndex }, AddLayerProcess, new object[] { image }));
             }
             }
         }
         }

+ 18 - 12
PixiEditor/Models/Controllers/UndoManager.cs

@@ -1,28 +1,34 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.Linq;
 using System.Linq;
 using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.DataHolders;
+using PixiEditor.ViewModels;
 
 
 namespace PixiEditor.Models.Controllers
 namespace PixiEditor.Models.Controllers
 {
 {
-    public static class UndoManager
+    public class UndoManager
     {
     {
-        private static bool lastChangeWasUndo;
+        private bool lastChangeWasUndo;
 
 
-        public static Stack<Change> UndoStack { get; set; } = new Stack<Change>();
+        public Stack<Change> UndoStack { get; set; } = new Stack<Change>();
 
 
-        public static Stack<Change> RedoStack { get; set; } = new Stack<Change>();
+        public Stack<Change> RedoStack { get; set; } = new Stack<Change>();
 
 
-        public static bool CanUndo => UndoStack.Count > 0;
+        public bool CanUndo => UndoStack.Count > 0;
 
 
-        public static bool CanRedo => RedoStack.Count > 0;
+        public bool CanRedo => RedoStack.Count > 0;
 
 
-        public static object MainRoot { get; set; }
+        public object MainRoot { get; set; }
+
+        public UndoManager()
+        {
+            SetMainRoot(ViewModelMain.Current.UndoSubViewModel);
+        }
 
 
         /// <summary>
         /// <summary>
         ///     Sets object(root) in which undo properties are stored.
         ///     Sets object(root) in which undo properties are stored.
         /// </summary>
         /// </summary>
         /// <param name="root">Parent object.</param>
         /// <param name="root">Parent object.</param>
-        public static void SetMainRoot(object root)
+        public void SetMainRoot(object root)
         {
         {
             MainRoot = root;
             MainRoot = root;
         }
         }
@@ -30,7 +36,7 @@ namespace PixiEditor.Models.Controllers
         /// <summary>
         /// <summary>
         ///     Adds property change to UndoStack.
         ///     Adds property change to UndoStack.
         /// </summary>
         /// </summary>
-        public static void AddUndoChange(Change change)
+        public void AddUndoChange(Change change)
         {
         {
             lastChangeWasUndo = false;
             lastChangeWasUndo = false;
 
 
@@ -47,7 +53,7 @@ namespace PixiEditor.Models.Controllers
         /// <summary>
         /// <summary>
         ///     Sets top property in UndoStack to Old Value.
         ///     Sets top property in UndoStack to Old Value.
         /// </summary>
         /// </summary>
-        public static void Undo()
+        public void Undo()
         {
         {
             lastChangeWasUndo = true;
             lastChangeWasUndo = true;
             Change change = UndoStack.Pop();
             Change change = UndoStack.Pop();
@@ -66,7 +72,7 @@ namespace PixiEditor.Models.Controllers
         /// <summary>
         /// <summary>
         ///     Sets top property from RedoStack to old value.
         ///     Sets top property from RedoStack to old value.
         /// </summary>
         /// </summary>
-        public static void Redo()
+        public void Redo()
         {
         {
             lastChangeWasUndo = true;
             lastChangeWasUndo = true;
             Change change = RedoStack.Pop();
             Change change = RedoStack.Pop();
@@ -82,7 +88,7 @@ namespace PixiEditor.Models.Controllers
             UndoStack.Push(change);
             UndoStack.Push(change);
         }
         }
 
 
-        private static void SetPropertyValue(object target, string propName, object value)
+        private void SetPropertyValue(object target, string propName, object value)
         {
         {
             string[] bits = propName.Split('.');
             string[] bits = propName.Split('.');
             for (int i = 0; i < bits.Length - 1; i++)
             for (int i = 0; i < bits.Length - 1; i++)

+ 47 - 0
PixiEditor/Models/DataHolders/Document.cs

@@ -1,4 +1,5 @@
 using System;
 using System;
+using System.Buffers;
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
 using System.IO;
 using System.IO;
 using System.Linq;
 using System.Linq;
@@ -8,8 +9,10 @@ using System.Windows.Media.Imaging;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Enums;
 using PixiEditor.Models.Enums;
+using PixiEditor.Models.IO;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Layers;
 using PixiEditor.Models.Position;
 using PixiEditor.Models.Position;
+using PixiEditor.ViewModels;
 
 
 namespace PixiEditor.Models.DataHolders
 namespace PixiEditor.Models.DataHolders
 {
 {
@@ -23,6 +26,8 @@ namespace PixiEditor.Models.DataHolders
         {
         {
             Width = width;
             Width = width;
             Height = height;
             Height = height;
+            RequestCloseDocumentCommand = new RelayCommand(RequestCloseDocument);
+            UndoManager = new UndoManager();
             DocumentSizeChanged?.Invoke(this, new DocumentSizeChangedEventArgs(0, 0, width, height));
             DocumentSizeChanged?.Invoke(this, new DocumentSizeChangedEventArgs(0, 0, width, height));
         }
         }
 
 
@@ -30,6 +35,8 @@ namespace PixiEditor.Models.DataHolders
 
 
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
 
 
+        public RelayCommand RequestCloseDocumentCommand { get; set; }
+
         private string documentFilePath = string.Empty;
         private string documentFilePath = string.Empty;
 
 
         public string DocumentFilePath
         public string DocumentFilePath
@@ -82,6 +89,20 @@ namespace PixiEditor.Models.DataHolders
             }
             }
         }
         }
 
 
+        private Selection selection = new Selection(Array.Empty<Coordinates>());
+
+        public Selection ActiveSelection
+        {
+            get => selection;
+            set
+            {
+                selection = value;
+                RaisePropertyChanged("ActiveSelection");
+            }
+        }
+
+        public UndoManager UndoManager { get; set; }
+
         public ObservableCollection<Layer> Layers { get; set; } = new ObservableCollection<Layer>();
         public ObservableCollection<Layer> Layers { get; set; } = new ObservableCollection<Layer>();
 
 
         public Layer ActiveLayer => Layers.Count > 0 ? Layers[ActiveLayerIndex] : null;
         public Layer ActiveLayer => Layers.Count > 0 ? Layers[ActiveLayerIndex] : null;
@@ -97,6 +118,24 @@ namespace PixiEditor.Models.DataHolders
             }
             }
         }
         }
 
 
+        public void SaveWithDialog()
+        {
+            bool savedSuccessfully = Exporter.SaveAsEditableFileWithDialog(this, out string path);
+            DocumentFilePath = path;
+            ChangesSaved = savedSuccessfully;
+        }
+
+        public void Save()
+        {
+            Save(DocumentFilePath);
+        }
+
+        public void Save(string path)
+        {
+            DocumentFilePath = Exporter.SaveAsEditableFile(this, path);
+            ChangesSaved = true;
+        }
+
         public ObservableCollection<Color> Swatches { get; set; } = new ObservableCollection<Color>();
         public ObservableCollection<Color> Swatches { get; set; } = new ObservableCollection<Color>();
 
 
         /// <summary>
         /// <summary>
@@ -247,6 +286,9 @@ namespace PixiEditor.Models.DataHolders
                 "Clip canvas"));
                 "Clip canvas"));
         }
         }
 
 
+        /// <summary>
+        /// Centers content inside document.
+        /// </summary>
         public void CenterContent()
         public void CenterContent()
         {
         {
             DoubleCords points = GetEdgePoints();
             DoubleCords points = GetEdgePoints();
@@ -277,6 +319,11 @@ namespace PixiEditor.Models.DataHolders
                     "Center content"));
                     "Center content"));
         }
         }
 
 
+        private void RequestCloseDocument(object parameter)
+        {
+            ViewModelMain.Current.DocumentSubViewModel.RequestCloseDocument(this);
+        }
+
         private int GetOffsetXForAnchor(int srcWidth, int destWidth, AnchorPoint anchor)
         private int GetOffsetXForAnchor(int srcWidth, int destWidth, AnchorPoint anchor)
         {
         {
             if (anchor.HasFlag(AnchorPoint.Center))
             if (anchor.HasFlag(AnchorPoint.Center))

+ 2 - 1
PixiEditor/Models/Tools/Tool.cs

@@ -1,5 +1,6 @@
 using System.Windows.Input;
 using System.Windows.Input;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
+using PixiEditor.Models.Controllers;
 using PixiEditor.Models.Tools.ToolSettings;
 using PixiEditor.Models.Tools.ToolSettings;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 using PixiEditor.Models.Tools.ToolSettings.Toolbars;
 
 
@@ -72,7 +73,7 @@ namespace PixiEditor.Models.Tools
         {
         {
         }
         }
 
 
-        public virtual void AfterAddedUndo()
+        public virtual void AfterAddedUndo(UndoManager undoManager)
         {
         {
         }
         }
     }
     }

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

@@ -58,7 +58,7 @@ namespace PixiEditor.Models.Tools.Tools
             }
             }
         }
         }
 
 
-        public override void AfterAddedUndo()
+        public override void AfterAddedUndo(UndoManager undoManager)
         {
         {
             if (currentSelection != null && currentSelection.Length != 0)
             if (currentSelection != null && currentSelection.Length != 0)
             {
             {
@@ -66,7 +66,7 @@ namespace PixiEditor.Models.Tools.Tools
                 foreach (var item in startPixelColors)
                 foreach (var item in startPixelColors)
                 {
                 {
                     BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(startSelection, item.Value);
                     BitmapPixelChanges beforeMovePixels = BitmapPixelChanges.FromArrays(startSelection, item.Value);
-                    Change changes = UndoManager.UndoStack.Peek();
+                    Change changes = undoManager.UndoStack.Peek();
                     int layerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.IndexOf(item.Key);
                     int layerIndex = ViewModelMain.Current.BitmapManager.ActiveDocument.Layers.IndexOf(item.Key);
 
 
                     ((LayerChange[])changes.OldValue).First(x => x.LayerIndex == layerIndex).PixelChanges.ChangedPixels
                     ((LayerChange[])changes.OldValue).First(x => x.LayerIndex == layerIndex).PixelChanges.ChangedPixels
@@ -86,7 +86,7 @@ namespace PixiEditor.Models.Tools.Tools
         {
         {
             if (currentSelection != null && currentSelection.Length == 0)
             if (currentSelection != null && currentSelection.Length == 0)
             {
             {
-                UndoManager.AddUndoChange(new Change(
+                ViewModelMain.Current.BitmapManager.ActiveDocument.UndoManager.AddUndoChange(new Change(
                     ApplyOffsets,
                     ApplyOffsets,
                     new object[] { startingOffsets },
                     new object[] { startingOffsets },
                     ApplyOffsets,
                     ApplyOffsets,
@@ -105,10 +105,10 @@ namespace PixiEditor.Models.Tools.Tools
                 ResetSelectionValues(start);
                 ResetSelectionValues(start);
 
 
                 // Move offset if no selection
                 // Move offset if no selection
-                if (ViewModelMain.Current.SelectionSubViewModel.ActiveSelection != null && 
-                    ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SelectedPoints.Count > 0)
+                Selection selection = ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection;
+                if (selection != null && selection.SelectedPoints.Count > 0)
                 {
                 {
-                    currentSelection = ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray();
+                    currentSelection = selection.SelectedPoints.ToArray();
                 }
                 }
                 else
                 else
                 {
                 {
@@ -161,7 +161,7 @@ namespace PixiEditor.Models.Tools.Tools
             currentSelection = TranslateSelection(end, out Coordinates[] previousSelection);
             currentSelection = TranslateSelection(end, out Coordinates[] previousSelection);
             if (updateViewModelSelection)
             if (updateViewModelSelection)
             {
             {
-                ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SetSelection(currentSelection, SelectionType.New);
+                ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.SetSelection(currentSelection, SelectionType.New);
             }
             }
 
 
             ClearSelectedPixels(layer, previousSelection);
             ClearSelectedPixels(layer, previousSelection);

+ 11 - 8
PixiEditor/Models/Tools/Tools/SelectTool.cs

@@ -34,23 +34,26 @@ namespace PixiEditor.Models.Tools.Tools
             SelectionType = selectionType;
             SelectionType = selectionType;
 
 
             oldSelection = null;
             oldSelection = null;
-            if (ViewModelMain.Current.SelectionSubViewModel.ActiveSelection != null &&
-                ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SelectedPoints != null)
+            Selection selection = ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection;
+            if (selection != null && selection.SelectedPoints != null)
             {
             {
-                oldSelection = ViewModelMain.Current.SelectionSubViewModel.ActiveSelection;
+                oldSelection = selection;
             }
             }
         }
         }
 
 
         public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
         public override void OnStoppedRecordingMouseUp(MouseEventArgs e)
         {
         {
-            if (ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SelectedPoints.Count() <= 1)
+            if (ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.Count() <= 1)
             {
             {
                 // If we have not selected multiple points, clear the selection
                 // If we have not selected multiple points, clear the selection
-                ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.Clear();
+                ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.Clear();
             }
             }
 
 
-            UndoManager.AddUndoChange(
-                new Change("ActiveSelection", oldSelection, ViewModelMain.Current.SelectionSubViewModel.ActiveSelection, "Select pixels", ViewModelMain.Current.SelectionSubViewModel));
+            ViewModelMain.Current.BitmapManager.ActiveDocument.UndoManager.AddUndoChange(
+                new Change("ActiveSelection", 
+                oldSelection,
+                ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection,
+                "Select pixels", ViewModelMain.Current.SelectionSubViewModel));
         }
         }
 
 
         public override void Use(Coordinates[] pixels)
         public override void Use(Coordinates[] pixels)
@@ -87,7 +90,7 @@ namespace PixiEditor.Models.Tools.Tools
         private void Select(Coordinates[] pixels)
         private void Select(Coordinates[] pixels)
         {
         {
             IEnumerable<Coordinates> selection = GetRectangleSelectionForPoints(pixels[^1], pixels[0]);
             IEnumerable<Coordinates> selection = GetRectangleSelectionForPoints(pixels[^1], pixels[0]);
-            ViewModelMain.Current.SelectionSubViewModel.ActiveSelection.SetSelection(selection, SelectionType);
+            ViewModelMain.Current.BitmapManager.ActiveDocument.ActiveSelection.SetSelection(selection, SelectionType);
         }
         }
     }
     }
 }
 }

+ 2 - 2
PixiEditor/ViewModels/SubViewModels/Main/ClipboardViewModel.cs

@@ -40,7 +40,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             Copy(null);
             Copy(null);
             Owner.BitmapManager.BitmapOperations.DeletePixels(
             Owner.BitmapManager.BitmapOperations.DeletePixels(
                 new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
                 new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
-                Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray());
+                Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.ToArray());
         }
         }
 
 
         public void Paste(object parameter)
         public void Paste(object parameter)
@@ -57,7 +57,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         {
         {
             ClipboardController.CopyToClipboard(
             ClipboardController.CopyToClipboard(
                 new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
                 new[] { Owner.BitmapManager.ActiveDocument.ActiveLayer },
-                Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray(),
+                Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.ToArray(),
                 Owner.BitmapManager.ActiveDocument.Width,
                 Owner.BitmapManager.ActiveDocument.Width,
                 Owner.BitmapManager.ActiveDocument.Height);
                 Owner.BitmapManager.ActiveDocument.Height);
         }
         }

+ 22 - 2
PixiEditor/ViewModels/SubViewModels/Main/DocumentViewModel.cs

@@ -1,6 +1,9 @@
-using System.Linq;
+using System;
+using System.Linq;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
+using PixiEditor.Models.DataHolders;
 using PixiEditor.Models.Dialogs;
 using PixiEditor.Models.Dialogs;
+using PixiEditor.Models.Enums;
 
 
 namespace PixiEditor.ViewModels.SubViewModels.Main
 namespace PixiEditor.ViewModels.SubViewModels.Main
 {
 {
@@ -30,11 +33,28 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             Owner.BitmapManager.ActiveDocument?.ClipCanvas();
             Owner.BitmapManager.ActiveDocument?.ClipCanvas();
         }
         }
 
 
+        public void RequestCloseDocument(Document document)
+        {
+            if (!document.ChangesSaved)
+            {
+                ConfirmationType result = ConfirmationDialog.Show(ConfirmationDialogMessage);
+                if (result == ConfirmationType.Yes)
+                {
+                    Owner.FileSubViewModel.SaveDocument(false);
+                }
+                else if (result == ConfirmationType.Canceled)
+                {
+                    return;
+                }
+            }
+            Owner.BitmapManager.CloseDocument(document);
+        }
+
         private void DeletePixels(object parameter)
         private void DeletePixels(object parameter)
         {
         {
             Owner.BitmapManager.BitmapOperations.DeletePixels(
             Owner.BitmapManager.BitmapOperations.DeletePixels(
                 new[] { Owner.BitmapManager.ActiveLayer },
                 new[] { Owner.BitmapManager.ActiveLayer },
-                Owner.SelectionSubViewModel.ActiveSelection.SelectedPoints.ToArray());
+                Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints.ToArray());
         }
         }
 
 
         private void OpenResizePopup(object parameter)
         private void OpenResizePopup(object parameter)

+ 12 - 21
PixiEditor/ViewModels/SubViewModels/Main/FileViewModel.cs

@@ -76,6 +76,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             if (dialog.ShowDialog())
             if (dialog.ShowDialog())
             {
             {
                 NewDocument(dialog.FileWidth, dialog.FileHeight, false);
                 NewDocument(dialog.FileWidth, dialog.FileHeight, false);
+                Owner.BitmapManager.ActiveDocument.DocumentFilePath = path;
                 Owner.BitmapManager.ActiveDocument.AddNewLayer(
                 Owner.BitmapManager.ActiveDocument.AddNewLayer(
                     "Image",
                     "Image",
                     Importer.ImportImage(dialog.FilePath, dialog.FileWidth, dialog.FileHeight));
                     Importer.ImportImage(dialog.FilePath, dialog.FileWidth, dialog.FileHeight));
@@ -105,22 +106,8 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
 
         private void Open(string path)
         private void Open(string path)
         {
         {
-            if (!Owner.BitmapManager.ActiveDocument.ChangesSaved)
-            {
-                var result = ConfirmationDialog.Show(DocumentViewModel.ConfirmationDialogMessage);
-                if (result == ConfirmationType.Yes)
-                {
-                    SaveDocument(null);
-                }
-                else if (result == ConfirmationType.Canceled)
-                {
-                    return;
-                }
-            }
-
             try
             try
             {
             {
-                Owner.ResetProgramStateValues();
                 if (path.EndsWith(".pixi"))
                 if (path.EndsWith(".pixi"))
                 {
                 {
                     OpenDocument(path);
                     OpenDocument(path);
@@ -129,6 +116,8 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
                 {
                 {
                     OpenFile(path);
                     OpenFile(path);
                 }
                 }
+
+                Owner.ResetProgramStateValues();
             }
             }
             catch (CorruptedFileException ex)
             catch (CorruptedFileException ex)
             {
             {
@@ -159,22 +148,24 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
             {
             {
                 Owner.BitmapManager.Documents.Add(Importer.ImportDocument(path));
                 Owner.BitmapManager.Documents.Add(Importer.ImportDocument(path));
             }
             }
+            else
+            {
+                Owner.BitmapManager.ActiveDocument = Owner.BitmapManager.Documents.First(y => y.DocumentFilePath == path);
+            }
         }
         }
 
 
         private void SaveDocument(object parameter)
         private void SaveDocument(object parameter)
         {
         {
             bool paramIsAsNew = parameter != null && parameter.ToString()?.ToLower() == "asnew";
             bool paramIsAsNew = parameter != null && parameter.ToString()?.ToLower() == "asnew";
-            if (paramIsAsNew || string.IsNullOrEmpty(Owner.BitmapManager.ActiveDocument.DocumentFilePath))
+            if (paramIsAsNew ||
+                string.IsNullOrEmpty(Owner.BitmapManager.ActiveDocument.DocumentFilePath) ||
+                !Owner.BitmapManager.ActiveDocument.DocumentFilePath.EndsWith(".pixi"))
             {
             {
-                bool savedSuccessfully = Exporter.SaveAsEditableFileWithDialog(Owner.BitmapManager.ActiveDocument, out string path);
-                Owner.BitmapManager.ActiveDocument.DocumentFilePath = path;
-
-                Owner.BitmapManager.ActiveDocument.ChangesSaved = savedSuccessfully;
+                Owner.BitmapManager.ActiveDocument.SaveWithDialog();
             }
             }
             else
             else
             {
             {
-                Exporter.SaveAsEditableFile(Owner.BitmapManager.ActiveDocument, Owner.BitmapManager.ActiveDocument.DocumentFilePath);
-                Owner.BitmapManager.ActiveDocument.ChangesSaved = true;
+                Owner.BitmapManager.ActiveDocument.Save();
             }
             }
         }
         }
 
 

+ 4 - 16
PixiEditor/ViewModels/SubViewModels/Main/SelectionViewModel.cs

@@ -13,40 +13,28 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
 
         public RelayCommand SelectAllCommand { get; set; }
         public RelayCommand SelectAllCommand { get; set; }
 
 
-        private Selection selection;
-
-        public Selection ActiveSelection
-        {
-            get => selection;
-            set
-            {
-                selection = value;
-                RaisePropertyChanged("ActiveSelection");
-            }
-        }
-
         public SelectionViewModel(ViewModelMain owner)
         public SelectionViewModel(ViewModelMain owner)
             : base(owner)
             : base(owner)
         {
         {
             DeselectCommand = new RelayCommand(Deselect, SelectionIsNotEmpty);
             DeselectCommand = new RelayCommand(Deselect, SelectionIsNotEmpty);
             SelectAllCommand = new RelayCommand(SelectAll, CanSelectAll);
             SelectAllCommand = new RelayCommand(SelectAll, CanSelectAll);
-            ActiveSelection = new Selection(Array.Empty<Coordinates>());
         }
         }
 
 
         public void SelectAll(object parameter)
         public void SelectAll(object parameter)
         {
         {
             SelectTool select = new SelectTool();
             SelectTool select = new SelectTool();
-            ActiveSelection.SetSelection(select.GetAllSelection(), SelectionType.New);
+            Owner.BitmapManager.ActiveDocument.ActiveSelection.SetSelection(select.GetAllSelection(), SelectionType.New);
         }
         }
 
 
         public void Deselect(object parameter)
         public void Deselect(object parameter)
         {
         {
-            ActiveSelection?.Clear();
+            Owner.BitmapManager.ActiveDocument.ActiveSelection?.Clear();
         }
         }
 
 
         public bool SelectionIsNotEmpty(object property)
         public bool SelectionIsNotEmpty(object property)
         {
         {
-            return ActiveSelection?.SelectedPoints != null && ActiveSelection.SelectedPoints.Count > 0;
+            var selectedPoints = Owner.BitmapManager.ActiveDocument.ActiveSelection.SelectedPoints;
+            return selectedPoints != null && selectedPoints.Count > 0;
         }
         }
 
 
         private bool CanSelectAll(object property)
         private bool CanSelectAll(object property)

+ 7 - 7
PixiEditor/ViewModels/SubViewModels/Main/UndoViewModel.cs

@@ -33,7 +33,6 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         {
         {
             UndoCommand = new RelayCommand(Undo, CanUndo);
             UndoCommand = new RelayCommand(Undo, CanUndo);
             RedoCommand = new RelayCommand(Redo, CanRedo);
             RedoCommand = new RelayCommand(Redo, CanRedo);
-            UndoManager.SetMainRoot(this);
         }
         }
 
 
         public void TriggerNewUndoChange(Tool toolUsed)
         public void TriggerNewUndoChange(Tool toolUsed)
@@ -46,8 +45,9 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
                 {
                 {
                     LayerChange[] newValues = changes.Select(x => x.Item1).ToArray();
                     LayerChange[] newValues = changes.Select(x => x.Item1).ToArray();
                     LayerChange[] oldValues = changes.Select(x => x.Item2).ToArray();
                     LayerChange[] oldValues = changes.Select(x => x.Item2).ToArray();
-                    UndoManager.AddUndoChange(new Change("UndoChanges", oldValues, newValues, root: this));
-                    toolUsed.AfterAddedUndo();
+                    Owner.BitmapManager.ActiveDocument.UndoManager.AddUndoChange(
+                        new Change("UndoChanges", oldValues, newValues, root: this));
+                    toolUsed.AfterAddedUndo(Owner.BitmapManager.ActiveDocument.UndoManager);
                 }
                 }
             }
             }
         }
         }
@@ -58,7 +58,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         /// <param name="parameter">CommandProperty.</param>
         /// <param name="parameter">CommandProperty.</param>
         public void Redo(object parameter)
         public void Redo(object parameter)
         {
         {
-            UndoManager.Redo();
+            Owner.BitmapManager.ActiveDocument.UndoManager.Redo();
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -68,7 +68,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         public void Undo(object parameter)
         public void Undo(object parameter)
         {
         {
             Owner.SelectionSubViewModel.Deselect(null);
             Owner.SelectionSubViewModel.Deselect(null);
-            UndoManager.Undo();
+            Owner.BitmapManager.ActiveDocument.UndoManager.Undo();
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -78,7 +78,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         /// <returns>True if can undo.</returns>
         /// <returns>True if can undo.</returns>
         private bool CanUndo(object property)
         private bool CanUndo(object property)
         {
         {
-            return UndoManager.CanUndo;
+            return Owner.BitmapManager.ActiveDocument.UndoManager.CanUndo;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -88,7 +88,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
         /// <returns>True if can redo.</returns>
         /// <returns>True if can redo.</returns>
         private bool CanRedo(object property)
         private bool CanRedo(object property)
         {
         {
-            return UndoManager.CanRedo;
+            return Owner.BitmapManager.ActiveDocument.UndoManager.CanRedo;
         }
         }
     }
     }
 }
 }

+ 1 - 4
PixiEditor/ViewModels/ViewModelMain.cs

@@ -144,9 +144,6 @@ namespace PixiEditor.ViewModels
         public void ResetProgramStateValues()
         public void ResetProgramStateValues()
         {
         {
             BitmapManager.PreviewLayer = null;
             BitmapManager.PreviewLayer = null;
-            UndoManager.UndoStack.Clear();
-            UndoManager.RedoStack.Clear();
-            SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             ViewportSubViewModel.CenterViewport();
             ViewportSubViewModel.CenterViewport();
         }
         }
 
 
@@ -230,7 +227,7 @@ namespace PixiEditor.ViewModels
 
 
         private void ActiveDocument_DocumentSizeChanged(object sender, DocumentSizeChangedEventArgs e)
         private void ActiveDocument_DocumentSizeChanged(object sender, DocumentSizeChangedEventArgs e)
         {
         {
-            SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
+            BitmapManager.ActiveDocument.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             ViewportSubViewModel.CenterViewport();
             ViewportSubViewModel.CenterViewport();
             BitmapManager.ActiveDocument.ChangesSaved = false;
             BitmapManager.ActiveDocument.ChangesSaved = false;
         }
         }

+ 1 - 1
PixiEditor/Views/MainWindow.xaml

@@ -169,7 +169,7 @@
                     <avalondock:DockingManager.LayoutItemContainerStyle>
                     <avalondock:DockingManager.LayoutItemContainerStyle>
                         <Style TargetType="{x:Type avalondock:LayoutItem}">
                         <Style TargetType="{x:Type avalondock:LayoutItem}">
                             <Setter Property="Title" Value="{Binding Model.Name}" />
                             <Setter Property="Title" Value="{Binding Model.Name}" />
-                            <Setter Property="CloseCommand" Value="{Binding Model.CloseCommand}" />
+                            <Setter Property="CloseCommand" Value="{Binding Model.RequestCloseDocumentCommand}" />
                             <Setter Property="CanClose" Value="{Binding Model.CanClose}" />
                             <Setter Property="CanClose" Value="{Binding Model.CanClose}" />
                         </Style>
                         </Style>
                     </avalondock:DockingManager.LayoutItemContainerStyle>
                     </avalondock:DockingManager.LayoutItemContainerStyle>

+ 5 - 4
PixiEditor/Views/UserControls/DrawingViewPort.xaml

@@ -63,11 +63,12 @@
                             </DataTemplate>
                             </DataTemplate>
                         </ItemsControl.ItemTemplate>
                         </ItemsControl.ItemTemplate>
                     </ItemsControl>
                     </ItemsControl>
-                    <Image VerticalAlignment="Top" HorizontalAlignment="Left" Source="{Binding SelectionSubViewModel.ActiveSelection.SelectionLayer.LayerBitmap}"
+                    <Image VerticalAlignment="Top" HorizontalAlignment="Left" 
+                           Source="{Binding BitmapManager.ActiveDocument.ActiveSelection.SelectionLayer.LayerBitmap}"
                                    RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"
                                    RenderOptions.BitmapScalingMode="NearestNeighbor" Stretch="Uniform"
-                                   Width="{Binding SelectionSubViewModel.ActiveSelection.SelectionLayer.Width}"
-                                   Height="{Binding SelectionSubViewModel.ActiveSelection.SelectionLayer.Height}" 
-                                   Margin="{Binding SelectionSubViewModel.ActiveSelection.SelectionLayer.Offset}" />
+                                   Width="{Binding BitmapManager.ActiveDocument.ActiveSelection.SelectionLayer.Width}"
+                                   Height="{Binding BitmapManager.ActiveDocument.ActiveSelection.SelectionLayer.Height}" 
+                                   Margin="{Binding BitmapManager.ActiveDocument.ActiveSelection.SelectionLayer.Offset}" />
                 </Canvas>
                 </Canvas>
             </vws:MainDrawingPanel.Item>
             </vws:MainDrawingPanel.Item>
         </vws:MainDrawingPanel>
         </vws:MainDrawingPanel>