Browse Source

Added file names, close confirmation for each element

TODO: 
- Remove document properly by clicking X,
- Undo
flabbet 4 years ago
parent
commit
bfeb340e88

+ 26 - 4
PixiEditor/Models/DataHolders/Document.cs

@@ -1,5 +1,6 @@
 using System;
 using System;
 using System.Collections.ObjectModel;
 using System.Collections.ObjectModel;
+using System.IO;
 using System.Linq;
 using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Media;
 using System.Windows.Media;
@@ -22,24 +23,45 @@ namespace PixiEditor.Models.DataHolders
         {
         {
             Width = width;
             Width = width;
             Height = height;
             Height = height;
+            DocumentSizeChanged?.Invoke(this, new DocumentSizeChangedEventArgs(0, 0, width, height));
         }
         }
 
 
         public event EventHandler<DocumentSizeChangedEventArgs> DocumentSizeChanged;
         public event EventHandler<DocumentSizeChangedEventArgs> DocumentSizeChanged;
 
 
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
         public event EventHandler<LayersChangedEventArgs> LayersChanged;
 
 
-        private string name = "Untitled";
+        private string documentFilePath = string.Empty;
 
 
-        public string Name
+        public string DocumentFilePath
         {
         {
-            get => name;
+            get => documentFilePath;
             set
             set
             {
             {
-                name = value;
+                documentFilePath = value;
+                RaisePropertyChanged(nameof(DocumentFilePath));
                 RaisePropertyChanged(nameof(Name));
                 RaisePropertyChanged(nameof(Name));
             }
             }
         }
         }
 
 
+        private bool changesSaved = true;
+
+        public bool ChangesSaved
+        {
+            get => changesSaved;
+            set
+            {
+                changesSaved = value;
+                RaisePropertyChanged(nameof(ChangesSaved));
+                RaisePropertyChanged(nameof(Name)); // This updates name so it shows asterisk if unsaved
+            }
+        }
+
+        public string Name
+        {
+            get => (string.IsNullOrEmpty(DocumentFilePath) ? "Untitled" : Path.GetFileName(DocumentFilePath))
+                + (!ChangesSaved ? " *" : string.Empty);
+        }
+
         public int Width
         public int Width
         {
         {
             get => width;
             get => width;

+ 12 - 14
PixiEditor/Models/IO/Exporter.cs

@@ -10,16 +10,12 @@ namespace PixiEditor.Models.IO
 {
 {
     public class Exporter
     public class Exporter
     {
     {
-        public static Size FileDimensions { get; set; }
-
-        public static string SaveDocumentPath { get; set; }
-
         /// <summary>
         /// <summary>
         ///     Saves document as .pixi file that contains all document data.
         ///     Saves document as .pixi file that contains all document data.
         /// </summary>
         /// </summary>
         /// <param name="document">Document to save.</param>
         /// <param name="document">Document to save.</param>
-        /// <param name="updateWorkspacePath">Should editor remember dialog path for further saves.</param>
-        public static bool SaveAsEditableFileWithDialog(Document document, bool updateWorkspacePath = false)
+        /// <param name="path">Path where file was saved.</param>
+        public static bool SaveAsEditableFileWithDialog(Document document, out string path)
         {
         {
             SaveFileDialog dialog = new SaveFileDialog
             SaveFileDialog dialog = new SaveFileDialog
             {
             {
@@ -28,21 +24,24 @@ namespace PixiEditor.Models.IO
             };
             };
             if ((bool)dialog.ShowDialog())
             if ((bool)dialog.ShowDialog())
             {
             {
-                SaveAsEditableFile(document, dialog.FileName, updateWorkspacePath);
+                path = SaveAsEditableFile(document, dialog.FileName);
                 return true;
                 return true;
             }
             }
 
 
+            path = string.Empty;
             return false;
             return false;
         }
         }
 
 
-        public static void SaveAsEditableFile(Document document, string path, bool updateWorkspacePath = false)
+        /// <summary>
+        /// Saves editable file to chosen path and returns it.
+        /// </summary>
+        /// <param name="document">Document to be saved.</param>
+        /// <param name="path">Path where to save file.</param>
+        /// <returns>Path.</returns>
+        public static string SaveAsEditableFile(Document document, string path)
         {
         {
             BinarySerialization.WriteToBinaryFile(path, new SerializableDocument(document));
             BinarySerialization.WriteToBinaryFile(path, new SerializableDocument(document));
-
-            if (updateWorkspacePath)
-            {
-                SaveDocumentPath = path;
-            }
+            return path;
         }
         }
 
 
         /// <summary>
         /// <summary>
@@ -64,7 +63,6 @@ namespace PixiEditor.Models.IO
                     return;
                     return;
                 }
                 }
 
 
-                FileDimensions = new Size(info.FileWidth, info.FileHeight);
                 SaveAsPng(info.FilePath, info.FileWidth, info.FileHeight, bitmap);
                 SaveAsPng(info.FilePath, info.FileWidth, info.FileHeight, bitmap);
             }
             }
         }
         }

+ 3 - 1
PixiEditor/Models/IO/Importer.cs

@@ -58,7 +58,9 @@ namespace PixiEditor.Models.IO
         {
         {
             try
             try
             {
             {
-                return BinarySerialization.ReadFromBinaryFile<SerializableDocument>(path).ToDocument();
+                Document doc = BinarySerialization.ReadFromBinaryFile<SerializableDocument>(path).ToDocument();
+                doc.DocumentFilePath = path;
+                return doc;
             }
             }
             catch (SerializationException)
             catch (SerializationException)
             {
             {

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

@@ -8,8 +8,6 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
     {
     {
         public const string ConfirmationDialogMessage = "Document was modified. Do you want to save changes?";
         public const string ConfirmationDialogMessage = "Document was modified. Do you want to save changes?";
 
 
-        public bool UnsavedDocumentModified { get; set; }
-
         public RelayCommand CenterContentCommand { get; set; }
         public RelayCommand CenterContentCommand { get; set; }
 
 
         public RelayCommand ClipCanvasCommand { get; set; }
         public RelayCommand ClipCanvasCommand { get; set; }

+ 13 - 11
PixiEditor/ViewModels/SubViewModels/Main/FileViewModel.cs

@@ -105,7 +105,7 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
 
         private void Open(string path)
         private void Open(string path)
         {
         {
-            if (Owner.DocumentSubViewModel.UnsavedDocumentModified)
+            if (!Owner.BitmapManager.ActiveDocument.ChangesSaved)
             {
             {
                 var result = ConfirmationDialog.Show(DocumentViewModel.ConfirmationDialogMessage);
                 var result = ConfirmationDialog.Show(DocumentViewModel.ConfirmationDialogMessage);
                 if (result == ConfirmationType.Yes)
                 if (result == ConfirmationType.Yes)
@@ -148,31 +148,33 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
                 if (Importer.IsSupportedFile(dialog.FileName))
                 if (Importer.IsSupportedFile(dialog.FileName))
                 {
                 {
                     Open(dialog.FileName);
                     Open(dialog.FileName);
+                    Owner.BitmapManager.ActiveDocument = Owner.BitmapManager.Documents.Last();
                 }
                 }
-
-                Owner.ViewportSubViewModel.CenterViewport();
             }
             }
         }
         }
 
 
         private void OpenDocument(string path)
         private void OpenDocument(string path)
         {
         {
-            Owner.BitmapManager.ActiveDocument = Importer.ImportDocument(path);
-            Exporter.SaveDocumentPath = path;
-            Owner.DocumentSubViewModel.UnsavedDocumentModified = false;
+            if (Owner.BitmapManager.Documents.Select(x => x.DocumentFilePath).All(y => y != path))
+            {
+                Owner.BitmapManager.Documents.Add(Importer.ImportDocument(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 || Exporter.SaveDocumentPath == null)
+            if (paramIsAsNew || string.IsNullOrEmpty(Owner.BitmapManager.ActiveDocument.DocumentFilePath))
             {
             {
-                var saved = Exporter.SaveAsEditableFileWithDialog(Owner.BitmapManager.ActiveDocument, !paramIsAsNew);
-                Owner.DocumentSubViewModel.UnsavedDocumentModified = Owner.DocumentSubViewModel.UnsavedDocumentModified && !saved;
+                bool savedSuccessfully = Exporter.SaveAsEditableFileWithDialog(Owner.BitmapManager.ActiveDocument, out string path);
+                Owner.BitmapManager.ActiveDocument.DocumentFilePath = path;
+
+                Owner.BitmapManager.ActiveDocument.ChangesSaved = savedSuccessfully;
             }
             }
             else
             else
             {
             {
-                Exporter.SaveAsEditableFile(Owner.BitmapManager.ActiveDocument, Exporter.SaveDocumentPath);
-                Owner.DocumentSubViewModel.UnsavedDocumentModified = false;
+                Exporter.SaveAsEditableFile(Owner.BitmapManager.ActiveDocument, Owner.BitmapManager.ActiveDocument.DocumentFilePath);
+                Owner.BitmapManager.ActiveDocument.ChangesSaved = true;
             }
             }
         }
         }
 
 

+ 2 - 1
PixiEditor/ViewModels/SubViewModels/Main/ViewportViewModel.cs

@@ -51,7 +51,8 @@ namespace PixiEditor.ViewModels.SubViewModels.Main
 
 
         public void CenterViewport()
         public void CenterViewport()
         {
         {
-            RecenterZoombox = !RecenterZoombox; // It's a trick to trigger change in UserControl
+            RecenterZoombox = false; // It's a trick to trigger change in UserControl
+            RecenterZoombox = true;
         }
         }
 
 
         private void ZoomViewport(object parameter)
         private void ZoomViewport(object parameter)

+ 46 - 9
PixiEditor/ViewModels/ViewModelMain.cs

@@ -2,6 +2,7 @@
 using System.Collections.Generic;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.ComponentModel;
 using System.Diagnostics;
 using System.Diagnostics;
+using System.Linq;
 using System.Windows;
 using System.Windows;
 using System.Windows.Input;
 using System.Windows.Input;
 using PixiEditor.Helpers;
 using PixiEditor.Helpers;
@@ -147,8 +148,6 @@ namespace PixiEditor.ViewModels
             UndoManager.RedoStack.Clear();
             UndoManager.RedoStack.Clear();
             SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             ViewportSubViewModel.CenterViewport();
             ViewportSubViewModel.CenterViewport();
-            Exporter.SaveDocumentPath = null;
-            DocumentSubViewModel.UnsavedDocumentModified = false;
         }
         }
 
 
         public bool DocumentIsNotNull(object property)
         public bool DocumentIsNotNull(object property)
@@ -163,10 +162,38 @@ namespace PixiEditor.ViewModels
                 throw new ArgumentException();
                 throw new ArgumentException();
             }
             }
 
 
-            ((CancelEventArgs)property).Cancel = true;
+            ((CancelEventArgs)property).Cancel = !RemoveDocumentsWithSaveConfirmation();
+        }
 
 
-            var result = ConfirmationType.No;
-            if (DocumentSubViewModel.UnsavedDocumentModified)
+        /// <summary>
+        /// Removes documents with unsaved changes confirmation dialog.
+        /// </summary>
+        /// <returns>If documents was removed successfully.</returns>
+        private bool RemoveDocumentsWithSaveConfirmation()
+        {
+            int docCount = BitmapManager.Documents.Count;
+            for (int i = 0; i < docCount; i++)
+            {
+                BitmapManager.ActiveDocument = BitmapManager.Documents.First();
+                bool canceled = !RemoveDocumentWithSaveConfirmation();
+                if (canceled)
+                {
+                    return false;
+                }
+            }
+
+            return true;
+        }
+
+        /// <summary>
+        /// Removes document with unsaved changes confirmation dialog.
+        /// </summary>
+        /// <returns>If document was removed successfully.</returns>
+        private bool RemoveDocumentWithSaveConfirmation()
+        {
+            ConfirmationType result = ConfirmationType.No;
+
+            if (!BitmapManager.ActiveDocument.ChangesSaved)
             {
             {
                 result = ConfirmationDialog.Show(DocumentViewModel.ConfirmationDialogMessage);
                 result = ConfirmationDialog.Show(DocumentViewModel.ConfirmationDialogMessage);
                 if (result == ConfirmationType.Yes)
                 if (result == ConfirmationType.Yes)
@@ -177,8 +204,15 @@ namespace PixiEditor.ViewModels
 
 
             if (result != ConfirmationType.Canceled)
             if (result != ConfirmationType.Canceled)
             {
             {
-                ((CancelEventArgs)property).Cancel = false;
+                BitmapManager.Documents.Remove(BitmapManager.ActiveDocument);
+
+                return true;
+            }
+            else
+            {
+                return false;
             }
             }
+
         }
         }
 
 
         private void OnStartup(object parameter)
         private void OnStartup(object parameter)
@@ -188,14 +222,17 @@ namespace PixiEditor.ViewModels
 
 
         private void BitmapManager_DocumentChanged(object sender, DocumentChangedEventArgs e)
         private void BitmapManager_DocumentChanged(object sender, DocumentChangedEventArgs e)
         {
         {
-            e.NewDocument.DocumentSizeChanged += ActiveDocument_DocumentSizeChanged;
+            if (e.NewDocument != null)
+            {
+                e.NewDocument.DocumentSizeChanged += ActiveDocument_DocumentSizeChanged;
+            }
         }
         }
 
 
         private void ActiveDocument_DocumentSizeChanged(object sender, DocumentSizeChangedEventArgs e)
         private void ActiveDocument_DocumentSizeChanged(object sender, DocumentSizeChangedEventArgs e)
         {
         {
             SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             SelectionSubViewModel.ActiveSelection = new Selection(Array.Empty<Coordinates>());
             ViewportSubViewModel.CenterViewport();
             ViewportSubViewModel.CenterViewport();
-            DocumentSubViewModel.UnsavedDocumentModified = true;
+            BitmapManager.ActiveDocument.ChangesSaved = false;
         }
         }
 
 
         private void MouseController_StoppedRecordingChanges(object sender, EventArgs e)
         private void MouseController_StoppedRecordingChanges(object sender, EventArgs e)
@@ -208,7 +245,7 @@ namespace PixiEditor.ViewModels
             ChangesController.AddChanges(
             ChangesController.AddChanges(
                 new LayerChange(e.PixelsChanged, e.ChangedLayerIndex),
                 new LayerChange(e.PixelsChanged, e.ChangedLayerIndex),
                 new LayerChange(e.OldPixelsValues, e.ChangedLayerIndex));
                 new LayerChange(e.OldPixelsValues, e.ChangedLayerIndex));
-            DocumentSubViewModel.UnsavedDocumentModified = true;
+            BitmapManager.ActiveDocument.ChangesSaved = false;
             if (BitmapManager.IsOperationTool())
             if (BitmapManager.IsOperationTool())
             {
             {
                 ColorsSubViewModel.AddSwatch(ColorsSubViewModel.PrimaryColor);
                 ColorsSubViewModel.AddSwatch(ColorsSubViewModel.PrimaryColor);

+ 0 - 2
PixiEditor/Views/MainWindow.xaml

@@ -5,9 +5,7 @@
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:vm="clr-namespace:PixiEditor.ViewModels"
         xmlns:vm="clr-namespace:PixiEditor.ViewModels"
         xmlns:vws="clr-namespace:PixiEditor.Views"
         xmlns:vws="clr-namespace:PixiEditor.Views"
-        xmlns:tools="clr-namespace:PixiEditor.Models.Tools"
         xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
         xmlns:converters="clr-namespace:PixiEditor.Helpers.Converters"
-        xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours"
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
         xmlns:ui="clr-namespace:PixiEditor.Helpers.UI"
         xmlns:ui="clr-namespace:PixiEditor.Helpers.UI"
         xmlns:cmd="http://www.galasoft.ch/mvvmlight" 
         xmlns:cmd="http://www.galasoft.ch/mvvmlight"