Browse Source

Project upload

flabbet 6 years ago
parent
commit
e8f339f188
65 changed files with 3462 additions and 0 deletions
  1. 6 0
      PixiEditor/App.config
  2. 14 0
      PixiEditor/App.xaml
  3. 17 0
      PixiEditor/App.xaml.cs
  4. 113 0
      PixiEditor/Helpers/Behaviours/AllowableCharactersTextBoxBehavior.cs
  5. 76 0
      PixiEditor/Helpers/Behaviours/HintTextBehavior.cs
  6. 47 0
      PixiEditor/Helpers/Behaviours/MouseBehaviour.cs
  7. 77 0
      PixiEditor/Helpers/Behaviours/TextBoxNumericFinisherBehavior.cs
  8. 22 0
      PixiEditor/Helpers/NotifyableObject.cs
  9. 56 0
      PixiEditor/Helpers/RelayCommand.cs
  10. 26 0
      PixiEditor/Helpers/ToolSizeToIntConverter.cs
  11. BIN
      PixiEditor/Images/Bucket image.png
  12. BIN
      PixiEditor/Images/Circle Image.png
  13. BIN
      PixiEditor/Images/Cross.png
  14. BIN
      PixiEditor/Images/Earser image.png
  15. BIN
      PixiEditor/Images/Lighten image.png
  16. BIN
      PixiEditor/Images/Line Image.png
  17. BIN
      PixiEditor/Images/Pen Image.png
  18. BIN
      PixiEditor/Images/Pipette image.png
  19. BIN
      PixiEditor/Images/Rectangle Image.png
  20. BIN
      PixiEditor/Images/transparent bg.png
  21. 61 0
      PixiEditor/Models/Change.cs
  22. 39 0
      PixiEditor/Models/Coordinates.cs
  23. 16 0
      PixiEditor/Models/CustomDialog.cs
  24. 20 0
      PixiEditor/Models/DCords.cs
  25. 13 0
      PixiEditor/Models/Enums/FileType.cs
  26. 45 0
      PixiEditor/Models/ExColor.cs
  27. 64 0
      PixiEditor/Models/ExportFileDialog.cs
  28. 106 0
      PixiEditor/Models/Exporter.cs
  29. 19 0
      PixiEditor/Models/FeedbackDialog.cs
  30. 76 0
      PixiEditor/Models/Layer.cs
  31. 49 0
      PixiEditor/Models/LayerGenerator.cs
  32. 21 0
      PixiEditor/Models/MousePositionConverter.cs
  33. 41 0
      PixiEditor/Models/NewFileDialog.cs
  34. 29 0
      PixiEditor/Models/ToolManager.cs
  35. 306 0
      PixiEditor/Models/Tools/ToolSet.cs
  36. 13 0
      PixiEditor/Models/Tools/ToolType.cs
  37. 116 0
      PixiEditor/Models/UndoManager.cs
  38. 211 0
      PixiEditor/PixiEditor.csproj
  39. 25 0
      PixiEditor/PixiEditor.sln
  40. 55 0
      PixiEditor/Properties/AssemblyInfo.cs
  41. 71 0
      PixiEditor/Properties/Resources.Designer.cs
  42. 117 0
      PixiEditor/Properties/Resources.resx
  43. 30 0
      PixiEditor/Properties/Settings.Designer.cs
  44. 7 0
      PixiEditor/Properties/Settings.settings
  45. 60 0
      PixiEditor/Styles/MenuButtonStyle.xaml
  46. 55 0
      PixiEditor/Styles/ThemeStyle.xaml
  47. 57 0
      PixiEditor/ViewModels/FeedbackDialogViewModel.cs
  48. 42 0
      PixiEditor/ViewModels/MenuButtonViewModel.cs
  49. 43 0
      PixiEditor/ViewModels/NewFileMenuViewModel.cs
  50. 109 0
      PixiEditor/ViewModels/SaveFilePopupViewModel.cs
  51. 38 0
      PixiEditor/ViewModels/ViewModelBase.cs
  52. 297 0
      PixiEditor/ViewModels/ViewModelMain.cs
  53. 46 0
      PixiEditor/Views/FeedbackDialog.xaml
  54. 27 0
      PixiEditor/Views/FeedbackDialog.xaml.cs
  55. 20 0
      PixiEditor/Views/MainDrawingPanel.xaml
  56. 99 0
      PixiEditor/Views/MainDrawingPanel.xaml.cs
  57. 206 0
      PixiEditor/Views/MainWindow.xaml
  58. 30 0
      PixiEditor/Views/MainWindow.xaml.cs
  59. 50 0
      PixiEditor/Views/MenuButton.xaml
  60. 55 0
      PixiEditor/Views/MenuButton.xaml.cs
  61. 52 0
      PixiEditor/Views/NewFilePopup.xaml
  62. 57 0
      PixiEditor/Views/NewFilePopup.xaml.cs
  63. 47 0
      PixiEditor/Views/SaveFilePopup.xaml
  64. 62 0
      PixiEditor/Views/SaveFilePopup.xaml.cs
  65. 6 0
      PixiEditor/packages.config

+ 6 - 0
PixiEditor/App.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
+    </startup>
+</configuration>

+ 14 - 0
PixiEditor/App.xaml

@@ -0,0 +1,14 @@
+<Application x:Class="PixiEditor.App"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:local="clr-namespace:PixiEditor"
+             StartupUri="Views/MainWindow.xaml">
+    <Application.Resources>
+        <ResourceDictionary>
+            <ResourceDictionary.MergedDictionaries>
+                <ResourceDictionary Source="Styles/MenuButtonStyle.xaml"/>
+                <ResourceDictionary Source="Styles/ThemeStyle.xaml"/>
+            </ResourceDictionary.MergedDictionaries>
+        </ResourceDictionary>
+    </Application.Resources>
+</Application>

+ 17 - 0
PixiEditor/App.xaml.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Data;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor
+{
+    /// <summary>
+    /// Interaction logic for App.xaml
+    /// </summary>
+    public partial class App : Application
+    {
+    }
+}

+ 113 - 0
PixiEditor/Helpers/Behaviours/AllowableCharactersTextBoxBehavior.cs

@@ -0,0 +1,113 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Interactivity;
+
+namespace PixiEditor.Helpers.Behaviours
+{
+    public class AllowableCharactersTextBoxBehavior : Behavior<TextBox>
+    {
+        public static readonly DependencyProperty RegularExpressionProperty =
+             DependencyProperty.Register("RegularExpression", typeof(string), typeof(AllowableCharactersTextBoxBehavior),
+             new FrameworkPropertyMetadata(".*"));
+        public string RegularExpression
+        {
+            get
+            {
+                return (string)base.GetValue(RegularExpressionProperty);
+            }
+            set
+            {
+                base.SetValue(RegularExpressionProperty, value);
+            }
+        }
+
+        public static readonly DependencyProperty MaxLengthProperty =
+            DependencyProperty.Register("MaxLength", typeof(int), typeof(AllowableCharactersTextBoxBehavior),
+            new FrameworkPropertyMetadata(int.MinValue));
+        public int MaxLength
+        {
+            get
+            {
+                return (int)base.GetValue(MaxLengthProperty);
+            }
+            set
+            {
+                base.SetValue(MaxLengthProperty, value);
+            }
+        }
+
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+            AssociatedObject.PreviewTextInput += OnPreviewTextInput;
+            DataObject.AddPastingHandler(AssociatedObject, OnPaste);
+        }
+
+        private void OnPaste(object sender, DataObjectPastingEventArgs e)
+        {
+            if (e.DataObject.GetDataPresent(DataFormats.Text))
+            {
+                string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));
+
+                if (!IsValid(text, true))
+                {
+                    e.CancelCommand();
+                }
+            }
+            else
+            {
+                e.CancelCommand();
+            }
+        }
+
+        void OnPreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
+        {
+            e.Handled = !IsValid(e.Text, false);
+        }
+
+        protected override void OnDetaching()
+        {
+            base.OnDetaching();
+            AssociatedObject.PreviewTextInput -= OnPreviewTextInput;
+            DataObject.RemovePastingHandler(AssociatedObject, OnPaste);
+        }
+
+        private bool IsValid(string newText, bool paste)
+        {
+            return !ExceedsMaxLength(newText, paste) && Regex.IsMatch(newText, RegularExpression);
+        }
+
+        private bool ExceedsMaxLength(string newText, bool paste)
+        {
+            if (MaxLength == 0) return false;
+
+            return LengthOfModifiedText(newText, paste) > MaxLength;
+        }
+
+        private int LengthOfModifiedText(string newText, bool paste)
+        {
+            var countOfSelectedChars = this.AssociatedObject.SelectedText.Length;
+            var caretIndex = this.AssociatedObject.CaretIndex;
+            string text = this.AssociatedObject.Text;
+
+            if (countOfSelectedChars > 0 || paste)
+            {
+                text = text.Remove(caretIndex, countOfSelectedChars);
+                return text.Length + newText.Length;
+            }
+            else
+            {
+                var insert = Keyboard.IsKeyToggled(Key.Insert);
+
+                return insert && caretIndex < text.Length ? text.Length : text.Length + newText.Length;
+            }
+        }
+    }
+}

+ 76 - 0
PixiEditor/Helpers/Behaviours/HintTextBehavior.cs

@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Interactivity;
+using System.Windows.Media;
+
+namespace PixiEditor.Helpers.Behaviours
+{
+    class HintTextBehavior : Behavior<TextBox>
+    {
+
+        private Brush _textColor;
+
+        public string Hint
+        {
+            get { return (string)GetValue(HintProperty); }
+            set { SetValue(HintProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for Hint.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty HintProperty =
+            DependencyProperty.Register("Hint", typeof(string), typeof(HintTextBehavior), new PropertyMetadata(string.Empty));
+
+
+
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+            AssociatedObject.GotFocus += AssociatedObject_GotFocus;
+            AssociatedObject.LostFocus += AssociatedObject_LostFocus;
+            _textColor = AssociatedObject.Foreground;
+            SetHint(true);
+        }
+
+        private void AssociatedObject_LostFocus(object sender, RoutedEventArgs e)
+        {
+            if(string.IsNullOrEmpty(AssociatedObject.Text) == true)
+            {
+                SetHint(true);
+            }
+        }
+
+        private void AssociatedObject_GotFocus(object sender, RoutedEventArgs e)
+        {
+            if(AssociatedObject.Text == Hint)
+            {
+                SetHint(false);
+            }
+        }
+
+        private void SetHint(bool active)
+        {
+            if (active == true)
+            {
+                AssociatedObject.Foreground = (SolidColorBrush)new BrushConverter().ConvertFromString("#7B7B7B");
+                AssociatedObject.Text = Hint;
+            }
+            else
+            {
+                AssociatedObject.Text = string.Empty;
+                AssociatedObject.Foreground = _textColor;
+            }
+        }
+
+        protected override void OnDetaching()
+        {
+            base.OnDetaching();
+            AssociatedObject.LostFocus -= AssociatedObject_LostFocus;          
+            AssociatedObject.GotFocus -= AssociatedObject_GotFocus;
+        }
+    }
+}

+ 47 - 0
PixiEditor/Helpers/Behaviours/MouseBehaviour.cs

@@ -0,0 +1,47 @@
+using PixiEditor.Views;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using Xceed.Wpf.Toolkit.Zoombox;
+
+namespace PixiEditor.Helpers.Behaviours {
+
+    public class MouseBehaviour : System.Windows.Interactivity.Behavior<FrameworkElement>
+    {
+        public static readonly DependencyProperty MouseYProperty = DependencyProperty.Register(
+            "MouseY", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));
+
+        public double MouseY
+        {
+            get { return (double)GetValue(MouseYProperty); }
+            set { SetValue(MouseYProperty, value); }
+        }
+
+        public static readonly DependencyProperty MouseXProperty = DependencyProperty.Register(
+            "MouseX", typeof(double), typeof(MouseBehaviour), new PropertyMetadata(default(double)));
+
+        public double MouseX
+        {
+            get { return (double)GetValue(MouseXProperty); }
+            set { SetValue(MouseXProperty, value); }
+        }
+
+        protected override void OnAttached()
+        {
+            AssociatedObject.MouseMove += AssociatedObjectOnMouseMove;
+        }
+
+        private void AssociatedObjectOnMouseMove(object sender, MouseEventArgs mouseEventArgs)
+        {
+            var pos = mouseEventArgs.GetPosition(AssociatedObject);
+            MouseX = pos.X;
+            MouseY = pos.Y;
+        }
+
+        protected override void OnDetaching()
+        {
+            AssociatedObject.MouseMove -= AssociatedObjectOnMouseMove;
+        }
+    }
+}

+ 77 - 0
PixiEditor/Helpers/Behaviours/TextBoxNumericFinisherBehavior.cs

@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Controls;
+using System.Windows.Interactivity;
+
+namespace PixiEditor.Helpers.Behaviours
+{
+    class TextBoxNumericFinisherBehavior : Behavior<TextBox>
+    {
+        private string _oldText; //Value of textbox before editing
+        private bool _valueConverted = false; //This bool is used to avoid double convertion if enter is hitted
+
+        protected override void OnAttached()
+        {
+            base.OnAttached();
+            AssociatedObject.LostKeyboardFocus += AssociatedObject_LostKeyboardFocus;
+            AssociatedObject.GotKeyboardFocus += AssociatedObject_GotKeyboardFocus;
+            AssociatedObject.KeyUp += AssociatedObject_KeyUp;
+            AssociatedObject.GotMouseCapture += AssociatedObject_GotMouseCapture;
+        }
+
+        private void AssociatedObject_GotMouseCapture(object sender, System.Windows.Input.MouseEventArgs e)
+        {
+            AssociatedObject.SelectAll(); //Selects all text on mouse click
+        }
+        
+        //Converts number to proper format if enter is clicked and moves focus to next object
+        private void AssociatedObject_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
+        {
+            if (e.Key != System.Windows.Input.Key.Enter) return;
+
+            ConvertValue();
+            AssociatedObject.MoveFocus(new System.Windows.Input.TraversalRequest(System.Windows.Input.FocusNavigationDirection.Next));
+        }
+
+        private void AssociatedObject_GotKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
+        {
+            _valueConverted = false;
+            _oldText = AssociatedObject.Text; //Sets old value when keyboard is focused on object
+        }
+
+        private void AssociatedObject_LostKeyboardFocus(object sender, System.Windows.Input.KeyboardFocusChangedEventArgs e)
+        {
+            ConvertValue();            
+        }
+
+        /// <summary>
+        /// Converts number from textbox to format "number px" ex. "15 px"
+        /// </summary>
+        private void ConvertValue()
+        {
+            if (_valueConverted == true) return;
+            if (int.TryParse(AssociatedObject.Text, out int result) == true)
+            {
+                AssociatedObject.Text = string.Format("{0} {1}", AssociatedObject.Text, "px");
+            }
+            else //If text in textbox isn't number, set it to old value
+            {
+                AssociatedObject.Text = _oldText;
+            }
+            _valueConverted = true;
+        }
+
+        protected override void OnDetaching()
+        {
+            base.OnDetaching();
+            AssociatedObject.LostKeyboardFocus -= AssociatedObject_LostKeyboardFocus;
+            AssociatedObject.GotKeyboardFocus -= AssociatedObject_GotKeyboardFocus;
+            AssociatedObject.KeyUp -= AssociatedObject_KeyUp;
+            AssociatedObject.GotMouseCapture -= AssociatedObject_GotMouseCapture;
+
+        }
+    }
+}

+ 22 - 0
PixiEditor/Helpers/NotifyableObject.cs

@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Helpers
+{
+    public class NotifyableObject : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged = delegate { };
+
+        protected void RaisePropertyChanged(string property)
+        {
+            if (property != null)
+            {
+                PropertyChanged(this, new PropertyChangedEventArgs(property));
+            }
+        }
+    }
+}

+ 56 - 0
PixiEditor/Helpers/RelayCommand.cs

@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace PixiEditor.Helpers
+{
+    public class RelayCommand : ICommand
+    {
+        #region Fields
+
+        readonly Action<object> _execute;
+        readonly Predicate<object> _canExecute;
+
+        #endregion // Fields
+
+        #region Constructors
+
+        public RelayCommand(Action<object> execute)
+            : this(execute, null)
+        {
+        }
+
+        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
+        {
+            if (execute == null)
+                throw new ArgumentNullException("execute");
+
+            _execute = execute;
+            _canExecute = canExecute;
+        }
+        #endregion // Constructors
+
+        #region ICommand Members
+
+        public bool CanExecute(object parameter)
+        {
+            return _canExecute == null ? true : _canExecute(parameter);
+        }
+
+        public event EventHandler CanExecuteChanged
+        {
+            add { CommandManager.RequerySuggested += value; }
+            remove { CommandManager.RequerySuggested -= value; }
+        }
+
+        public void Execute(object parameter)
+        {
+            _execute(parameter);
+        }
+
+        #endregion // ICommand Members
+    }
+}

+ 26 - 0
PixiEditor/Helpers/ToolSizeToIntConverter.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Data;
+
+namespace PixiEditor.Helpers
+{
+    [ValueConversion(typeof(string), typeof(int))]
+    class ToolSizeToIntConverter : IValueConverter
+    {
+        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            return string.Format("{0} {1}", value, "px");
+        }
+
+        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
+        {
+            if (string.IsNullOrWhiteSpace(value as string)) return null;
+            string slicedString = value.ToString().Split(' ').First();
+            return int.Parse(slicedString);
+        }
+    }
+}

BIN
PixiEditor/Images/Bucket image.png


BIN
PixiEditor/Images/Circle Image.png


BIN
PixiEditor/Images/Cross.png


BIN
PixiEditor/Images/Earser image.png


BIN
PixiEditor/Images/Lighten image.png


BIN
PixiEditor/Images/Line Image.png


BIN
PixiEditor/Images/Pen Image.png


BIN
PixiEditor/Images/Pipette image.png


BIN
PixiEditor/Images/Rectangle Image.png


BIN
PixiEditor/Images/transparent bg.png


+ 61 - 0
PixiEditor/Models/Change.cs

@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models
+{
+    public class Change
+    {
+        private object _oldValue;
+
+        public object OldValue
+        {
+            get { return _oldValue; }
+            set { _oldValue = value; }
+        }
+
+        private object _newValue;
+
+        public object NewValue
+        {
+            get { return _newValue; }
+            set { _newValue = value; }
+        }
+
+        private object _type;
+
+        public object Type
+        {
+            get { return _type; }
+            set { _type = value; }
+        }
+
+        private string _description;
+
+        public string Description
+        {
+            get { return _description; }
+            set { _description = value; }
+        }
+
+        private string _property;
+
+        public string Property
+        {
+            get { return _property; }
+            set { _property = value; }
+        }
+
+
+        public Change(string property, object oldValue, object newValue, string description = null)
+        {
+            Property = property;
+            OldValue = oldValue;
+            NewValue = newValue;
+            Description = description;
+        }
+
+    }
+}

+ 39 - 0
PixiEditor/Models/Coordinates.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models
+{
+    public class Coordinates
+    {
+        private int _X;
+
+        public int X
+        {
+            get { return _X; }
+            set { _X = value; }
+        }
+
+        private int _Y;
+
+        public int Y
+        {
+            get { return _Y; }
+            set { _Y = value; }
+        }
+
+        public Coordinates()
+        {
+
+        }
+
+        public Coordinates(int x, int y)
+        {
+            X = x;
+            Y = y;
+        }
+
+    }
+}

+ 16 - 0
PixiEditor/Models/CustomDialog.cs

@@ -0,0 +1,16 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor.Models
+{
+    public abstract class CustomDialog : NotifyableObject
+    {
+        public abstract bool ShowDialog();
+    }
+}

+ 20 - 0
PixiEditor/Models/DCords.cs

@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models
+{
+    public class DCords
+    {
+        public Coordinates Coords1 { get; set; }
+        public Coordinates Coords2 { get; set; }
+        
+        public DCords(Coordinates cords1, Coordinates cords2)
+        {
+            Coords1 = cords1;
+            Coords2 = cords2;
+        }
+    }
+}

+ 13 - 0
PixiEditor/Models/Enums/FileType.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models.Enums
+{
+    public enum FileType
+    {
+        PNG = 0,
+    }
+}

+ 45 - 0
PixiEditor/Models/ExColor.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Media;
+
+namespace PixiEditor.Models
+{
+    public class ExColor
+    {
+        /// <summary>
+        /// Creates color with corrected brightness.
+        /// </summary>
+        /// <param name="color">Color to correct.</param>
+        /// <param name="correctionFactor">The brightness correction factor. Must be between -1 and 1. 
+        /// Negative values produce darker colors.</param>
+        /// <returns>
+        /// Corrected <see cref="Color"/> structure.
+        /// </returns>
+        public static Color ChangeColorBrightness(Color color, float correctionFactor)
+        {
+            float red = (float)color.R;
+            float green = (float)color.G;
+            float blue = (float)color.B;
+
+            if (correctionFactor < 0)
+            {
+                correctionFactor = 1 + correctionFactor;
+                red *= correctionFactor;
+                green *= correctionFactor;
+                blue *= correctionFactor;
+            }
+            else
+            {
+                red = (255 - red) * correctionFactor + red;
+                green = (255 - green) * correctionFactor + green;
+                blue = (255 - blue) * correctionFactor + blue;
+            }
+
+            return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
+        }
+    }
+}

+ 64 - 0
PixiEditor/Models/ExportFileDialog.cs

@@ -0,0 +1,64 @@
+using PixiEditor.Views;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor.Models
+{
+    public class ExportFileDialog : CustomDialog
+    {
+
+        private int _fileWidth;
+
+        public int FileWidth
+        {
+            get { return _fileWidth; }
+            set { if (_fileWidth != value) { _fileWidth = value; RaisePropertyChanged("Width"); } }
+        }
+
+
+        private int _fileHeight;
+
+        public int FileHeight
+        {
+            get { return _fileHeight; }
+            set { if (_fileHeight != value) { _fileHeight = value; RaisePropertyChanged("FileHeight"); } }
+        }
+
+
+        private string _filePath;
+
+        public string FilePath
+        {
+            get { return _filePath; }
+            set { if (_filePath != value) { _filePath = value; RaisePropertyChanged("FilePath"); } }
+        }
+
+        public ExportFileDialog(Size fileDimensions)
+        {
+            FileHeight = (int)fileDimensions.Height;
+            FileWidth = (int)fileDimensions.Width;
+        }
+
+        public override bool ShowDialog()
+        {
+            SaveFilePopup popup = new SaveFilePopup
+            {
+                SaveWidth = FileWidth,
+                SaveHeight = FileHeight
+            };
+            popup.ShowDialog();
+            if (popup.DialogResult == true)
+            {
+                FileWidth = popup.SaveWidth;
+                FileHeight = popup.SaveHeight;
+                FilePath = popup.SavePath;
+            }
+            return (bool)popup.DialogResult;
+        }
+    }
+}

+ 106 - 0
PixiEditor/Models/Exporter.cs

@@ -0,0 +1,106 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Microsoft.Win32;
+using PixiEditor.Models.Enums;
+
+namespace PixiEditor.Models
+{
+    public class Exporter
+    {
+        public static string _savePath = null;
+        public static Size _fileDimensions;
+
+        /// <summary>
+        /// Creates ExportFileDialog to get width, height and path of file.
+        /// </summary>
+        /// <param name="type">Type of file to be saved in.</param>
+        /// <param name="imageToSave">Image to be saved as file.</param>
+        public static void Export(FileType type,Image imageToSave, Size fileDimensions)
+        {
+                ExportFileDialog info = new ExportFileDialog(fileDimensions);
+                //If OK on dialog has been clicked
+                if (info.ShowDialog() == true)
+                {
+                    //If sizes are incorrect
+                    if(info.FileWidth < imageToSave.Width || info.FileHeight < imageToSave.Height)
+                    {
+                        MessageBox.Show("Incorrect height or width value", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+                        return;
+                    }
+
+                    _savePath = info.FilePath;
+                    _fileDimensions = new Size(info.FileWidth, info.FileHeight);
+                    SaveAsPng(info.FilePath, (int)imageToSave.Width, (int)imageToSave.Height, info.FileHeight, info.FileWidth, imageToSave);
+                }
+        }
+
+        /// <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="imageToSave">Image to be saved as file.</param>
+        public static void ExportWithoutDialog(FileType type, Image imageToSave)
+        {
+            try
+            {
+                SaveAsPng(_savePath, (int)imageToSave.Width, (int)imageToSave.Height, (int)_fileDimensions.Height, (int)_fileDimensions.Width, imageToSave);
+            }
+            catch(Exception ex)
+            {
+                MessageBox.Show(ex.Message);
+            }
+        }
+        /// <summary>
+        /// Saves image to PNG file
+        /// </summary>
+        /// <param name="savePath">Save file path</param>
+        /// <param name="originalWidth">Original width of image</param>
+        /// <param name="originalHeight">Original height of image</param>
+        /// <param name="exportWidth">File width</param>
+        /// <param name="exportHeight">File height</param>
+        /// <param name="imageToExport">Image to be saved</param>
+        private static void SaveAsPng(string savePath, int originalWidth, int originalHeight, int exportWidth, int exportHeight, Image imageToExport)
+        {
+            Rect bounds = VisualTreeHelper.GetDescendantBounds(imageToExport);
+            double dpi = 96d;
+
+
+            RenderTargetBitmap rtb = new RenderTargetBitmap(originalWidth * (exportWidth / originalWidth), originalHeight * (exportHeight/originalHeight), dpi, dpi, PixelFormats.Default);
+
+
+            DrawingVisual dv = new DrawingVisual();
+            using (DrawingContext dc = dv.RenderOpen())
+            {
+                VisualBrush vb = new VisualBrush(imageToExport);
+                dc.DrawRectangle(vb, null, new Rect(new Point(), new Size(originalWidth * (exportWidth / originalWidth), originalHeight * (exportHeight / originalHeight))));
+            }
+
+            rtb.Render(dv);
+            BitmapEncoder pngEncoder = new PngBitmapEncoder();
+            pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
+
+            try
+            {
+                MemoryStream ms = new MemoryStream();
+
+                pngEncoder.Save(ms);
+                ms.Close();
+
+                File.WriteAllBytes(savePath, ms.ToArray());
+            }
+            catch (Exception err)
+            {
+                System.Windows.MessageBox.Show(err.ToString(), "Error", MessageBoxButton.OK, MessageBoxImage.Error);
+            }
+        }
+    }
+}

+ 19 - 0
PixiEditor/Models/FeedbackDialog.cs

@@ -0,0 +1,19 @@
+using PixiEditor.Views;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models
+{
+    public class FeedbackMenuDialog : CustomDialog
+    {
+        public override bool ShowDialog()
+        {
+            FeedbackDialog dialog = new FeedbackDialog();
+            dialog.ShowDialog();
+            return (bool)dialog.DialogResult;
+        }
+    }
+}

+ 76 - 0
PixiEditor/Models/Layer.cs

@@ -0,0 +1,76 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace PixiEditor.Models
+{
+    public class Layer : NotifyableObject
+    {
+        private WriteableBitmap _layerBitmap;
+
+        public WriteableBitmap LayerBitmap
+        {
+            get { return _layerBitmap; }
+            set {
+                _layerBitmap = value;
+                RaisePropertyChanged("LayerBitmap");
+            }
+        }
+
+        private Image _layerImage;
+
+        public Image LayerImage
+        {
+            get { return _layerImage; }
+            set {
+                _layerImage = value;
+                RaisePropertyChanged("LayerImage");
+            }
+        }
+
+        private int _width;
+
+        public int Width
+        {
+            get { return _width; }
+            set { _width = value; RaisePropertyChanged("Width"); }
+        }
+
+        private int _height;
+
+        public int Height
+        {
+            get { return _height; }
+            set { _height = value; RaisePropertyChanged("Height"); }
+        }
+
+
+
+        public Layer(int width, int height)
+        {
+            Layer layer = LayerGenerator.GenerateLayer(width, height);
+            LayerBitmap = layer.LayerBitmap;
+            LayerImage = layer.LayerImage;
+            Width = width;
+            Height = height;
+        }
+
+
+        public Layer(WriteableBitmap layerBitmap, Image layerImage)
+        {
+            LayerBitmap = layerBitmap;
+            LayerImage = layerImage;
+            Width = (int)layerImage.Width;
+            Height = (int)layerImage.Height;
+        }
+    }
+}

+ 49 - 0
PixiEditor/Models/LayerGenerator.cs

@@ -0,0 +1,49 @@
+using PixiEditor.Models.Tools;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace PixiEditor.Models
+{
+    public static class LayerGenerator 
+    {
+        /// <summary>
+        /// Generating useable layer with image and bitmap
+        /// </summary>
+        /// <param name="imageWidth">Width of layer.</param>
+        /// <param name="imageHeight">Height of layer.</param>
+        /// <returns></returns>
+        public static Layer GenerateLayer(int imageWidth, int imageHeight)
+        {
+            Image image = new Image();
+            RenderOptions.SetBitmapScalingMode(image, BitmapScalingMode.NearestNeighbor);
+            RenderOptions.SetEdgeMode(image, EdgeMode.Aliased);
+            image.Stretch = Stretch.Uniform;
+            image.Width = imageWidth;
+            image.Height = imageHeight;
+            WriteableBitmap bitmap = GenerateBitmap(imageWidth, imageHeight);
+            image.Source = bitmap;
+            return new Layer(bitmap, image);
+        }
+
+        /// <summary>
+        /// Generates bitmap ready to work with
+        /// </summary>
+        /// <param name="bitmapWidth">Width of bitmap.</param>
+        /// <param name="imageHeight">Height of bitmap.</param>
+        /// <returns></returns>
+        private static WriteableBitmap GenerateBitmap(int bitmapWidth, int imageHeight)
+        {
+            WriteableBitmap bitmap = BitmapFactory.New(bitmapWidth, imageHeight);
+            bitmap.Clear(Colors.Transparent);
+            return bitmap;
+        }      
+    }
+}

+ 21 - 0
PixiEditor/Models/MousePositionConverter.cs

@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace PixiEditor.Models
+{
+    public static class MousePositionConverter
+    {
+        public static Coordinates MousePositionToCoordinates(Layer baseLayer, Point mousePosition)
+        {
+            int xCoord = (int)(mousePosition.X / baseLayer.Width);
+            int yCoord = (int)(mousePosition.Y / baseLayer.Height);
+            return new Coordinates(xCoord, yCoord);
+        }
+    }
+}

+ 41 - 0
PixiEditor/Models/NewFileDialog.cs

@@ -0,0 +1,41 @@
+using PixiEditor.Views;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor.Models
+{
+    public class NewFileDialog : CustomDialog
+    {
+
+        private int _width;
+
+        public int Width
+        {
+            get { return _width; }
+            set { if (_width != value) { _width = value; RaisePropertyChanged("Width"); } }
+        }
+
+
+        private int _height;
+
+        public int Height
+        {
+            get { return _height; }
+            set { if (_height != value) { _height = value; RaisePropertyChanged("Height"); } }
+        }
+
+        public override bool ShowDialog()
+        {
+            Window popup = new NewFilePopup();
+            popup.ShowDialog();
+            Height = (popup as NewFilePopup).FileHeight;
+            Width = (popup as NewFilePopup).FileWidth;
+            return (bool)popup.DialogResult;
+        }
+    }
+}

+ 29 - 0
PixiEditor/Models/ToolManager.cs

@@ -0,0 +1,29 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models.Tools
+{
+    class ToolManager : NotifyableObject
+    {
+
+        private ToolType _activeTool;
+
+        public ToolType ActiveTool
+        {
+            get { return _activeTool; }
+            set
+            {
+                if (_activeTool != value)
+                {
+                    _activeTool = value;
+                    RaisePropertyChanged("ActiveTool");
+                }
+            }
+        }
+    }
+}

+ 306 - 0
PixiEditor/Models/Tools/ToolSet.cs

@@ -0,0 +1,306 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+
+namespace PixiEditor.Models.Tools
+{
+    public class ToolSet
+    {
+        private Coordinates _activeCoordinates = new Coordinates();
+        private bool _toolIsExecuting = false;
+        private int _asyncDelay = 15;
+
+        public Layer ExecuteTool(Layer layer, Coordinates startingCoords, Color color,int toolSize, ToolType tool)
+        {
+            if (toolSize < 1) return null;
+            Layer cLayer = layer;
+            WriteableBitmap oldBitmap = layer.LayerBitmap.Clone();
+            Image oldImage = layer.LayerImage;
+            oldImage.Source = oldBitmap;
+            switch (tool)
+            {
+                case ToolType.Pen:
+                    cLayer.LayerBitmap = DrawPixel(cLayer.LayerBitmap, startingCoords, toolSize,color);
+                    break;
+                case ToolType.Bucket:
+                    cLayer.LayerBitmap = FloodFill(cLayer.LayerBitmap, startingCoords, color);
+                    break;
+                case ToolType.Line:
+                    if (_toolIsExecuting == false)
+                    {
+                        LineAsync(cLayer, startingCoords, color, toolSize);
+                    }
+                    break;
+                case ToolType.Circle:
+                    if(_toolIsExecuting == false)
+                    {
+                        CircleAsync(cLayer, startingCoords, color);
+                    }
+                    break;
+                case ToolType.Rectangle:
+                    if(_toolIsExecuting == false)
+                    {
+                        RectangleAsync(cLayer, startingCoords, color);
+                    }
+                    break;              
+                case ToolType.Earser:
+                    cLayer.LayerBitmap = DrawPixel(cLayer.LayerBitmap, startingCoords, toolSize, Colors.Transparent);
+                    break;
+                case ToolType.Lighten:
+                    if(Mouse.LeftButton == MouseButtonState.Pressed)
+                    {
+                        cLayer.LayerBitmap = Lighten(cLayer.LayerBitmap, startingCoords);
+                    }
+                    else if(Mouse.RightButton == MouseButtonState.Pressed)
+                    {
+                        cLayer.LayerBitmap = Darken(cLayer.LayerBitmap, startingCoords);
+                    }
+                    break;
+                default:
+                    break;
+            }
+            if (tool != ToolType.ColorPicker)
+            {
+                UndoManager.RecordChanges("ActiveLayer", new Layer(oldBitmap, oldImage), cLayer, string.Format("{0} Tool.", tool.ToString()));
+            }
+            return cLayer;
+        }
+        /// <summary>
+        /// Not working yet.
+        /// </summary>
+        /// <param name="bitmap"></param>
+        /// <param name="pixelCoordinates"></param>
+        /// <param name="color"></param>
+        /// <param name="highlightThickness"></param>
+        public static void HighlightPixel(WriteableBitmap bitmap,Coordinates pixelCoordinates, Color color, int highlightThickness)
+        {
+            bitmap.Clear();
+            bitmap.Blit(new Rect(new Size(bitmap.Width, bitmap.Height)), bitmap, new Rect(new Size(bitmap.Width, bitmap.Height)), WriteableBitmapExtensions.BlendMode.Additive);
+            DCords centerCords = CalculateThicknessCenter(pixelCoordinates, highlightThickness);
+            bitmap.FillRectangle(centerCords.Coords1.X, centerCords.Coords1.Y, centerCords.Coords2.X, centerCords.Coords2.Y, color);
+        }
+
+        /// <summary>
+        /// Updates coordinates in order to some tools work
+        /// </summary>
+        /// <param name="cords">Current coordinates</param>
+        public void UpdateCoordinates(Coordinates cords)
+        {
+                _activeCoordinates = cords;
+        }
+
+        /// <summary>
+        /// Fills pixel(s) with choosen color
+        /// </summary>
+        /// <param name="canvas">Bitmap to operate on.</param>
+        /// <param name="pixelPosition">Coordinates of pixel.</param>
+        /// <param name="color">Color to be set.</param>
+        private WriteableBitmap DrawPixel(WriteableBitmap canvas, Coordinates pixelPosition,int thickness,Color color)
+        {
+            WriteableBitmap bm = canvas;
+            int x1, y1, x2, y2;
+            DCords centeredCoords = CalculateThicknessCenter(pixelPosition, thickness);
+            x1 = centeredCoords.Coords1.X;
+            y1 = centeredCoords.Coords1.Y;
+            x2 = centeredCoords.Coords2.X;
+            y2 = centeredCoords.Coords2.Y;
+            bm.FillRectangle(x1, y1, x2, y2, color);
+            return bm;
+        }
+
+        private static DCords CalculateThicknessCenter(Coordinates startPosition, int thickness)
+        {
+            int x1, x2, y1, y2;
+            if (thickness % 2 == 0)
+            {
+                x2 = startPosition.X + thickness / 2;
+                y2 = startPosition.Y + thickness / 2;
+                x1 = x2 - thickness;
+                y1 = y2 - thickness;
+            }
+            else
+            {
+                x2 = startPosition.X + (((thickness - 1) / 2) + 1);
+                y2 = startPosition.Y + (((thickness - 1) / 2) + 1);
+                x1 = x2 - thickness;
+                y1 = y2 - thickness;
+            }
+            return new DCords(new Coordinates(x1, y1), new Coordinates(x2, y2));
+        }
+
+        /// <summary>
+        /// Fills area with color (forest fire alghoritm)
+        /// </summary>
+        /// <param name="canvas">Bitmap to operate on</param>
+        /// <param name="pixelPosition">Position of starting pixel</param>
+        /// <param name="color">Fills area with this color</param>
+        private WriteableBitmap FloodFill(WriteableBitmap canvas, Coordinates pixelPosition, Color color)
+        {
+            WriteableBitmap bm = canvas;
+            Color colorToReplace = bm.GetPixel(pixelPosition.X, pixelPosition.Y);
+            var stack = new Stack<Tuple<int, int>>();
+            stack.Push(Tuple.Create(pixelPosition.X, pixelPosition.Y));
+
+            while (stack.Count > 0)
+            {
+                var point = stack.Pop();
+                if (point.Item1 < 0 || point.Item1 > bm.Height - 1) continue;
+                if (point.Item2 < 0 || point.Item2 > bm.Width - 1) continue;
+                if (bm.GetPixel(point.Item1, point.Item2) == color) continue;
+
+                if (bm.GetPixel(point.Item1, point.Item2) == colorToReplace)
+                {
+                    bm.SetPixel(point.Item1, point.Item2, color);
+                    stack.Push(Tuple.Create(point.Item1, point.Item2 - 1));
+                    stack.Push(Tuple.Create(point.Item1 + 1, point.Item2));
+                    stack.Push(Tuple.Create(point.Item1, point.Item2 + 1));
+                    stack.Push(Tuple.Create(point.Item1 - 1, point.Item2));
+                }
+            }
+            return bm;
+        }
+
+        /// <summary>
+        /// Draws line in canvas 
+        /// </summary>
+        /// <param name="layer">Layer to operate on</param>
+        /// <param name="coordinates">Starting coordinates, usually click point</param>
+        /// <param name="color">Does it really need a description?</param> 
+        private async void LineAsync(Layer layer, Coordinates coordinates, Color color, int size)
+        {
+            WriteableBitmap wb = layer.LayerBitmap;
+            _toolIsExecuting = true;
+            //clones bitmap before line
+            WriteableBitmap writeableBitmap = wb.Clone();
+            //While Mouse buttons are pressed, clears current bitmap, pastes cloned bitmap and draws line, on each iteration
+            while (Mouse.LeftButton == MouseButtonState.Pressed || Mouse.RightButton == MouseButtonState.Pressed)
+            {
+                wb.Clear();
+                wb.Blit(new Rect(new Size(layer.Width, layer.Height)), writeableBitmap, new Rect(new Size(layer.Width, layer.Height)), WriteableBitmapExtensions.BlendMode.Additive);
+                    wb.DrawLineBresenham(coordinates.X, coordinates.Y, _activeCoordinates.X, _activeCoordinates.Y, color);
+                await Task.Delay(_asyncDelay);
+            }           
+            _toolIsExecuting = false;
+        }
+
+        /// <summary>
+        /// Draws circle on bitmap.
+        /// </summary>
+        /// <param name="layer">Layer to operate on.</param>
+        /// <param name="coordinates">Starting pixel coordinates.</param>
+        /// <param name="color">Circle color.</param>
+        private async void CircleAsync(Layer layer, Coordinates coordinates, Color color)
+        {
+            WriteableBitmap wb = layer.LayerBitmap;
+            //Basically does the same like rectangle method, but with different shape
+            _toolIsExecuting = true;
+            WriteableBitmap bitmap = wb.Clone();
+            while (Mouse.LeftButton == MouseButtonState.Pressed || Mouse.RightButton == MouseButtonState.Pressed)
+            {
+                wb.Clear();
+                wb.Blit(new Rect(new Size(layer.Width, layer.Height)), bitmap, new Rect(new Size(layer.Width, layer.Height)), WriteableBitmapExtensions.BlendMode.Additive);
+                if (coordinates.X > _activeCoordinates.X && coordinates.Y > _activeCoordinates.Y)
+                {
+                    wb.DrawEllipse(_activeCoordinates.X, _activeCoordinates.Y, coordinates.X, coordinates.Y, color);
+                }
+                else if (coordinates.X < _activeCoordinates.X && coordinates.Y < _activeCoordinates.Y)
+                {
+                    wb.DrawEllipse(coordinates.X, coordinates.Y, _activeCoordinates.X, _activeCoordinates.Y, color);
+                }
+                else if (coordinates.Y > _activeCoordinates.Y)
+                {
+                    wb.DrawEllipse(coordinates.X, _activeCoordinates.Y, _activeCoordinates.X, coordinates.Y, color);
+                }
+                else
+                {
+                    wb.DrawEllipse(_activeCoordinates.X, coordinates.Y, coordinates.X, _activeCoordinates.Y, color);
+                }
+                await Task.Delay(_asyncDelay);
+            }
+            _toolIsExecuting = false;
+        }
+
+        /// <summary>
+        /// Draws rectangle on bitmap
+        /// </summary>
+        /// <param name="layer">Layer to operate on</param>
+        /// <param name="coordinates">Starting pixel coordinate</param>
+        /// <param name="color">Rectangle color</param>
+        private async void RectangleAsync(Layer layer, Coordinates coordinates, Color color)
+        {
+            WriteableBitmap wb = layer.LayerBitmap;
+            _toolIsExecuting = true;
+            WriteableBitmap writeableBitmap = wb.Clone();
+            while (Mouse.LeftButton == MouseButtonState.Pressed || Mouse.RightButton == MouseButtonState.Pressed)
+            {
+                //Two lines below are responsible for clearing last rectangle (on mouse move), to live show rectangle on bitmap
+                wb.Clear();
+                wb.Blit(new Rect(new Size(layer.Width, layer.Height)), writeableBitmap, new Rect(new Size(layer.Width, layer.Height)), WriteableBitmapExtensions.BlendMode.Additive);
+                //Those ifs are changing direction of rectangle. In other words: flips rectangle on X and Y axis when needed
+                if (coordinates.X > _activeCoordinates.X && coordinates.Y > _activeCoordinates.Y)
+                {
+                    wb.DrawRectangle(_activeCoordinates.X, _activeCoordinates.Y, coordinates.X, coordinates.Y, color);
+                }
+                else if (coordinates.X < _activeCoordinates.X && coordinates.Y < _activeCoordinates.Y)
+                {
+                    wb.DrawRectangle(coordinates.X, coordinates.Y, _activeCoordinates.X, _activeCoordinates.Y, color);
+                }
+                else if (coordinates.Y > _activeCoordinates.Y)
+                {
+                    wb.DrawRectangle(coordinates.X, _activeCoordinates.Y, _activeCoordinates.X, coordinates.Y, color);
+                }
+                else
+                {
+                    wb.DrawRectangle(_activeCoordinates.X, coordinates.Y, coordinates.X, _activeCoordinates.Y, color);
+                }
+                await Task.Delay(_asyncDelay);
+            }            
+            _toolIsExecuting = false;
+        }
+        /// <summary>
+        /// Returns color of pixel.
+        /// </summary>
+        /// <param name="layer">Layer in which bitmap with pixels are stored.</param>
+        /// <param name="coordinates">Pixel coordinate.</param>
+        /// <returns></returns>
+        public static Color ColorPicker(Layer layer, Coordinates coordinates)
+        {
+            return layer.LayerBitmap.GetPixel(coordinates.X, coordinates.Y);
+        }
+        /// <summary>
+        /// Ligtens pixel color.
+        /// </summary>
+        /// <param name="bitmap">Bitmap to work on.</param>
+        /// <param name="coordinates">Pixel coordinates.</param>
+        /// <returns></returns>
+        private WriteableBitmap Lighten(WriteableBitmap bitmap, Coordinates coordinates)
+        {
+            WriteableBitmap wb = bitmap;
+            Color newColor = ExColor.ChangeColorBrightness(wb.GetPixel(coordinates.X, coordinates.Y), 0.1f);
+            wb.SetPixel(coordinates.X, coordinates.Y, newColor);
+            return wb;
+        }
+        /// <summary>
+        /// Darkens pixel color.
+        /// </summary>
+        /// <param name="bitmap">Bitmap to work on.</param>
+        /// <param name="coordinates">Pixel coordinates.</param>
+        /// <returns></returns>
+        private WriteableBitmap Darken(WriteableBitmap bitmap, Coordinates coordinates)
+        {
+            WriteableBitmap wb = bitmap;
+            Color newColor = ExColor.ChangeColorBrightness(wb.GetPixel(coordinates.X, coordinates.Y), -0.06f);
+            wb.SetPixel(coordinates.X, coordinates.Y, newColor);
+            return wb;
+        }
+    }
+}

+ 13 - 0
PixiEditor/Models/Tools/ToolType.cs

@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PixiEditor.Models.Tools
+{
+    public enum ToolType
+    {
+        Pen = 0, Bucket, Line, Circle, Rectangle, ColorPicker, Earser, Lighten
+    }
+}

+ 116 - 0
PixiEditor/Models/UndoManager.cs

@@ -0,0 +1,116 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Media;
+
+namespace PixiEditor.Models
+{
+    public static class UndoManager
+    {
+        public static Stack<Change> UndoStack { get; set; } = new Stack<Change>(); 
+        public static Stack<Change> RedoStack { get; set; } = new Stack<Change>();
+        private static bool _stopRecording = false; 
+        private static List<Change> _recordedChanges = new List<Change>();
+        private static bool _lastChangeWasUndo = false;
+        public static bool CanUndo
+        {
+            get
+            {
+                return UndoStack.Count > 0;
+            }
+        }
+        public static bool CanRedo
+        {
+            get
+            {
+                return RedoStack.Count > 0;
+            }
+        }
+
+        public static object MainRoot { get; set; }
+
+        /// <summary>
+        /// Sets object(root) in which undo properties are stored.
+        /// </summary>
+        /// <param name="root">Parent object.</param>
+        public static void SetMainRoot(object root)
+        {
+            MainRoot = root;
+        }
+
+        /// <summary>
+        /// Records changes, used to save multiple changes as one
+        /// </summary>
+        /// <param name="property">Record property name.</param>
+        /// <param name="oldValue">Old change value.</param>
+        /// <param name="newValue">New change value.</param>
+        /// <param name="undoDescription">Description of change.</param>
+        public static void RecordChanges(string property, object oldValue, object newValue, string undoDescription = null)
+        {
+            if (_stopRecording == false)
+            {
+                _recordedChanges.Add(new Change(property, oldValue, newValue, undoDescription));
+            }
+        }
+
+        /// <summary>
+        /// Stops recording changes and saves it as one.
+        /// </summary>
+        public static void StopRecording()
+        {
+                _stopRecording = true;
+            if (_recordedChanges.Count > 0)
+            {
+                Change changeToSave = _recordedChanges[0];
+                AddUndoChange(changeToSave.Property, changeToSave.OldValue, changeToSave.NewValue, changeToSave.Description);
+                _recordedChanges.Clear();
+            }
+            _stopRecording = false;
+        }
+        /// <summary>
+        /// Adds property change to UndoStack
+        /// </summary>
+        /// <param name="property">Changed property name.</param>
+        /// <param name="oldValue">Old value of property.</param>
+        /// <param name="newValue">New value of property.</param>
+        /// <param name="undoDescription">Description of change.</param>
+        public static void AddUndoChange(string property, object oldValue, object newValue, string undoDescription = null)
+        {
+            if(_lastChangeWasUndo == false && RedoStack.Count > 0)
+            {
+                RedoStack.Clear();
+            }
+            _lastChangeWasUndo = false;
+            UndoStack.Push(new Change(property, oldValue, newValue, undoDescription));
+
+        }
+        /// <summary>
+        /// Sets top property in UndoStack to Old Value
+        /// </summary>
+        public static void Undo()
+        {
+            _lastChangeWasUndo = true;
+            PropertyInfo propInfo = MainRoot.GetType().GetProperty(UndoStack.Peek().Property);
+            propInfo.SetValue(MainRoot, UndoStack.Peek().OldValue);
+            RedoStack.Push(UndoStack.Pop());
+            UndoStack.Pop();
+        }
+
+        /// <summary>
+        /// Sets top property from RedoStack to old value
+        /// </summary>
+        public static void Redo()
+        {
+            _lastChangeWasUndo = true;
+            PropertyInfo propinfo = MainRoot.GetType().GetProperty(RedoStack.Peek().Property);
+            propinfo.SetValue(MainRoot, RedoStack.Pop().OldValue);
+        }
+    }
+}

+ 211 - 0
PixiEditor/PixiEditor.csproj

@@ -0,0 +1,211 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{04324995-2B67-402A-A427-F35AFA014D05}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <RootNamespace>PixiEditor</RootNamespace>
+    <AssemblyName>PixiEditor</AssemblyName>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Windows.Interactivity, Version=4.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <HintPath>packages\Expression.Blend.Sdk.1.0.2\lib\net45\System.Windows.Interactivity.dll</HintPath>
+    </Reference>
+    <Reference Include="System.Xml" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Net.Http" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="WriteableBitmapEx.Wpf, Version=1.5.0.0, Culture=neutral, PublicKeyToken=50375ca6144f1c69, processorArchitecture=MSIL">
+      <HintPath>packages\WriteableBitmapEx.1.5.1.0\lib\net40\WriteableBitmapEx.Wpf.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.AvalonDock, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.AvalonDock.Themes.Aero, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.AvalonDock.Themes.Metro, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.AvalonDock.Themes.VS2010, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.DataGrid, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.DataGrid.dll</HintPath>
+    </Reference>
+    <Reference Include="Xceed.Wpf.Toolkit, Version=3.4.0.0, Culture=neutral, PublicKeyToken=3e4669d2f30244f4, processorArchitecture=MSIL">
+      <HintPath>packages\Extended.Wpf.Toolkit.3.4.0\lib\net40\Xceed.Wpf.Toolkit.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="Helpers\Behaviours\AllowableCharactersTextBoxBehavior.cs" />
+    <Compile Include="Helpers\Behaviours\HintTextBehavior.cs" />
+    <Compile Include="Helpers\Behaviours\MouseBehaviour.cs" />
+    <Compile Include="Helpers\Behaviours\TextBoxNumericFinisherBehavior.cs" />
+    <Compile Include="Helpers\NotifyableObject.cs" />
+    <Compile Include="Helpers\RelayCommand.cs" />
+    <Compile Include="Helpers\ToolSizeToIntConverter.cs" />
+    <Compile Include="Models\Change.cs" />
+    <Compile Include="Models\Coordinates.cs" />
+    <Compile Include="Models\CustomDialog.cs" />
+    <Compile Include="Models\DCords.cs" />
+    <Compile Include="Models\Enums\FileType.cs" />
+    <Compile Include="Models\ExColor.cs" />
+    <Compile Include="Models\Exporter.cs" />
+    <Compile Include="Models\FeedbackDialog.cs" />
+    <Compile Include="Models\LayerGenerator.cs" />
+    <Compile Include="Models\Layer.cs" />
+    <Compile Include="Models\MousePositionConverter.cs" />
+    <Compile Include="Models\NewFileDialog.cs" />
+    <Compile Include="Models\ExportFileDialog.cs" />
+    <Compile Include="Models\Tools\ToolSet.cs" />
+    <Compile Include="Models\ToolManager.cs" />
+    <Compile Include="Models\Tools\ToolType.cs" />
+    <Compile Include="Models\UndoManager.cs" />
+    <Compile Include="ViewModels\FeedbackDialogViewModel.cs" />
+    <Compile Include="ViewModels\MenuButtonViewModel.cs" />
+    <Compile Include="ViewModels\NewFileMenuViewModel.cs" />
+    <Compile Include="ViewModels\SaveFilePopupViewModel.cs" />
+    <Compile Include="ViewModels\ViewModelBase.cs" />
+    <Compile Include="ViewModels\ViewModelMain.cs" />
+    <Compile Include="Views\FeedbackDialog.xaml.cs">
+      <DependentUpon>FeedbackDialog.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Views\MainDrawingPanel.xaml.cs">
+      <DependentUpon>MainDrawingPanel.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Views\MenuButton.xaml.cs">
+      <DependentUpon>MenuButton.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Views\NewFilePopup.xaml.cs">
+      <DependentUpon>NewFilePopup.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="Views\SaveFilePopup.xaml.cs">
+      <DependentUpon>SaveFilePopup.xaml</DependentUpon>
+    </Compile>
+    <Page Include="Styles\ThemeStyle.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\FeedbackDialog.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\MainDrawingPanel.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\MainWindow.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Views\MainWindow.xaml.cs">
+      <DependentUpon>MainWindow.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Page Include="Styles\MenuButtonStyle.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\MenuButton.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\NewFilePopup.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+    <Page Include="Views\SaveFilePopup.xaml">
+      <SubType>Designer</SubType>
+      <Generator>MSBuild:Compile</Generator>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="packages.config" />
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Images\Lighten image.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Images\Bucket image.png" />
+    <Resource Include="Images\Earser image.png" />
+    <Resource Include="Images\Circle Image.png" />
+    <Resource Include="Images\Line Image.png" />
+    <Resource Include="Images\Pen Image.png" />
+    <Resource Include="Images\Pipette image.png" />
+    <Resource Include="Images\Rectangle Image.png" />
+    <Resource Include="Images\transparent bg.png" />
+  </ItemGroup>
+  <ItemGroup>
+    <Resource Include="Images\Cross.png" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>

+ 25 - 0
PixiEditor/PixiEditor.sln

@@ -0,0 +1,25 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.27703.2042
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PixiEditor", "PixiEditor.csproj", "{04324995-2B67-402A-A427-F35AFA014D05}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{04324995-2B67-402A-A427-F35AFA014D05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{04324995-2B67-402A-A427-F35AFA014D05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{04324995-2B67-402A-A427-F35AFA014D05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{04324995-2B67-402A-A427-F35AFA014D05}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {F514506B-7EFD-425F-9491-0C9D4ED0266B}
+	EndGlobalSection
+EndGlobal

+ 55 - 0
PixiEditor/Properties/AssemblyInfo.cs

@@ -0,0 +1,55 @@
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PixiEditor")]
+[assembly: AssemblyDescription("Lighweighted Pixel Art editor.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PixiEditor")]
+[assembly: AssemblyCopyright("Copyright ©  2018")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+//In order to begin building localizable applications, set
+//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+//inside a <PropertyGroup>.  For example, if you are using US english
+//in your source files, set the <UICulture> to en-US.  Then uncomment
+//the NeutralResourceLanguage attribute below.  Update the "en-US" in
+//the line below to match the UICulture setting in the project file.
+
+//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
+                                     //(used if a resource is not found in the page,
+                                     // or application resource dictionaries)
+    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
+                                              //(used if a resource is not found in the page,
+                                              // app, or any theme specific resource dictionaries)
+)]
+
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]

+ 71 - 0
PixiEditor/Properties/Resources.Designer.cs

@@ -0,0 +1,71 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PixiEditor.Properties
+{
+
+
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources
+    {
+
+        private static global::System.Resources.ResourceManager resourceMan;
+
+        private static global::System.Globalization.CultureInfo resourceCulture;
+
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources()
+        {
+        }
+
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager
+        {
+            get
+            {
+                if ((resourceMan == null))
+                {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("PixiEditor.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture
+        {
+            get
+            {
+                return resourceCulture;
+            }
+            set
+            {
+                resourceCulture = value;
+            }
+        }
+    }
+}

+ 117 - 0
PixiEditor/Properties/Resources.resx

@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>

+ 30 - 0
PixiEditor/Properties/Settings.Designer.cs

@@ -0,0 +1,30 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace PixiEditor.Properties
+{
+
+
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
+    {
+
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+
+        public static Settings Default
+        {
+            get
+            {
+                return defaultInstance;
+            }
+        }
+    }
+}

+ 7 - 0
PixiEditor/Properties/Settings.settings

@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>

+ 60 - 0
PixiEditor/Styles/MenuButtonStyle.xaml

@@ -0,0 +1,60 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+                    xmlns:local="clr-namespace:PixiEditor.Styles">
+    <Style TargetType="Button" x:Key="MenuButton">
+        <Setter Property="Height" Value="30"/>
+        <Setter Property="Width" Value="60"/>
+        <Setter Property="Background" Value="Transparent"/>
+        <Setter Property="Foreground" Value="Snow"/>
+        <Setter Property="BorderThickness" Value="0"/>
+    </Style>
+    
+    <Style TargetType="Button" x:Key="MenuInsideButtonStyle">
+        <Setter Property="Height" Value="20"/>
+        <Setter Property="Width" Value="185"/>
+        <Setter Property="Background" Value="Transparent"/>
+        <Setter Property="Foreground" Value="Snow"/>
+        <Setter Property="BorderThickness" Value="0"/>
+        <Setter Property="HorizontalContentAlignment" Value="Left"/>
+        <Setter Property="OverridesDefaultStyle" Value="True"/>
+        <Setter Property="DataContext" Value="{DynamicResource ViewModelMain}"/>
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Grid Background="{TemplateBinding Background}">
+                        <ContentPresenter x:Name="MyContentPresenter"
+                                          Content="{TemplateBinding Content}"/>
+                    </Grid>
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+        <Style.Triggers>
+            <Trigger Property="IsEnabled" Value="False">
+                <Setter Property="Background" Value="Transparent"/>
+                <Setter Property="Foreground" Value="DarkGray"/>
+            </Trigger>
+            <Trigger Property="IsMouseOver" Value="True">
+                <Setter Property="Background" Value="#666666"/>
+            </Trigger>
+        </Style.Triggers>
+    </Style>
+
+    <Style TargetType="ListView" x:Key="MenuListViewStyle">
+        <Setter Property="Background" Value="#343636"/>
+        <Setter Property="Height" Value="300"/>
+        <Setter Property="Width" Value="200"/>
+        <Style.Resources>
+            <Style TargetType="ContentControl">
+                <Setter Property="Foreground" Value="Snow"/>
+                <Setter Property="Margin" Value="0,0,0,2"/>
+                <Setter Property="Background" Value="Transparent"/>
+                <Setter Property="BorderThickness" Value="0"/>
+                <Setter Property="HorizontalContentAlignment" Value="Left"/>
+                <Setter Property="Height" Value="290"/>
+                <Setter Property="Width" Value="185"/>
+            </Style>
+        </Style.Resources>
+    </Style>
+   
+
+</ResourceDictionary>

+ 55 - 0
PixiEditor/Styles/ThemeStyle.xaml

@@ -0,0 +1,55 @@
+<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+                    xmlns:local="clr-namespace:PixiEditor.Styles">
+
+    <Style TargetType="Button" x:Key="DarkRoundButton">
+        <Setter Property="Background" Value="#404040"/>
+        <Setter Property="Foreground" Value="White"/>
+        <Setter Property="FontSize" Value="22"/>
+        <Setter Property="SnapsToDevicePixels" Value="True"/>
+
+        <Setter Property="Template">
+            <Setter.Value>
+                <ControlTemplate TargetType="Button">
+                    <Border CornerRadius="4" Background="{TemplateBinding Background}">
+                        <ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                    </Border>
+
+                    <ControlTemplate.Triggers>
+                        <Trigger Property="IsEnabled" Value="False">
+                            <Setter Property="Background" Value="#404040"/>
+                            <Setter Property="Foreground" Value="White"/>
+                            <Setter Property="Cursor" Value="Arrow"/>
+                        </Trigger>
+                        <Trigger Property="IsMouseOver" Value="True">
+                            <Setter Property="Background" Value="#FF515151"/>
+                            <Setter Property="Foreground" Value="White"/>
+                            <Setter Property="Cursor" Value="Hand"/>
+                        </Trigger>
+                        <Trigger Property="IsPressed" Value="True">
+                            <Setter Property="Background" Value="#505050"/>
+                            <Setter Property="Foreground" Value="White"/>
+                        </Trigger>
+                    </ControlTemplate.Triggers>
+
+                </ControlTemplate>
+            </Setter.Value>
+        </Setter>
+    </Style>
+
+
+    <Style TargetType="TextBox" x:Key="DarkTextBoxStyle">
+        <Setter Property="Background" Value="#202020"/>
+        <Setter Property="BorderThickness" Value="1"/>
+        <Setter Property="BorderBrush" Value="#404040"/>
+        <Setter Property="Foreground" Value="Snow"/>
+    </Style>
+
+    <Style TargetType="Button" x:Key="ToolButtonStyle">
+        <Setter Property="Height" Value="52"/>
+        <Setter Property="Width" Value="52"/>
+        <Setter Property="VerticalAlignment" Value="Top"/>
+        <Setter Property="HorizontalAlignment" Value="Center"/>
+        <Setter Property="Margin" Value="0,10,0,0"/>
+    </Style>
+</ResourceDictionary>

+ 57 - 0
PixiEditor/ViewModels/FeedbackDialogViewModel.cs

@@ -0,0 +1,57 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Mail;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor.ViewModels
+{
+    class FeedbackDialogViewModel : ViewModelBase
+    {
+        public RelayCommand CloseButtonCommand { get; set; }
+        public RelayCommand SendButtonCommand { get; set; }
+
+
+        private string _mailFrom;
+
+        public string MailFrom
+        {
+            get { return _mailFrom; }
+            set { if (_mailFrom != value) { _mailFrom = value; RaisePropertyChanged("MailFrom"); } }
+        }
+
+
+        private string _emailBody;
+
+        public string EmailBody
+        {
+            get { return _emailBody; }
+            set { if (_emailBody != value) { _emailBody = value; RaisePropertyChanged("EmailBody"); } }
+        }
+
+        public FeedbackDialogViewModel()
+        {
+            CloseButtonCommand = new RelayCommand(CloseWindow);
+            SendButtonCommand = new RelayCommand(Send, CanSend);
+        }
+
+        private void CloseWindow(object parameter)
+        {
+            ((Window)parameter).DialogResult = false;
+            base.CloseButton(parameter);
+        }
+
+        private void Send(object parameter)
+        {
+            base.CloseButton(parameter);
+        }
+
+        private bool CanSend(object property)
+        {
+            return !string.IsNullOrWhiteSpace(MailFrom);
+        }
+    }
+}

+ 42 - 0
PixiEditor/ViewModels/MenuButtonViewModel.cs

@@ -0,0 +1,42 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+
+namespace PixiEditor.ViewModels
+{
+    class MenuButtonViewModel : ViewModelBase
+    {
+        public RelayCommand OpenListViewCommand { get; set; }
+        public RelayCommand CloseListViewCommand { get; set; }
+        private Visibility _listViewVisibility;
+
+        public Visibility ListViewVisibility
+        {
+            get { return _listViewVisibility; }
+            set { _listViewVisibility = value; RaisePropertyChanged("ListViewVisibility"); }
+        }
+
+
+        public MenuButtonViewModel()
+        {
+            OpenListViewCommand = new RelayCommand(OpenListView);
+            CloseListViewCommand = new RelayCommand(CloseListView);
+            ListViewVisibility = Visibility.Hidden;
+
+        }
+
+        private void OpenListView(object parameter)
+        {
+            ListViewVisibility = (ListViewVisibility == Visibility.Hidden) ? Visibility.Visible : Visibility.Hidden;
+        }
+
+        private void CloseListView(object parameter)
+        {
+            ListViewVisibility = Visibility.Hidden;
+        }
+    }
+}

+ 43 - 0
PixiEditor/ViewModels/NewFileMenuViewModel.cs

@@ -0,0 +1,43 @@
+using PixiEditor.Helpers;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace PixiEditor.ViewModels
+{
+    class NewFileMenuViewModel : ViewModelBase
+    {
+        public RelayCommand OkCommand { get; set; }
+        public RelayCommand CloseCommand { get; set; }
+        public RelayCommand DragMoveCommand { get; set; }
+
+        public NewFileMenuViewModel()
+        {
+            OkCommand = new RelayCommand(OkButton);
+            CloseCommand = new RelayCommand(CloseWindow);
+            DragMoveCommand = new RelayCommand(MoveWindow);
+        }
+
+        private void OkButton(object parameter)
+        {
+            ((Window)parameter).DialogResult = true;
+            ((Window)parameter).Close();
+        }
+
+        private void CloseWindow(object parameter)
+        {
+            ((Window)parameter).DialogResult = false;
+            base.CloseButton(parameter);
+        }
+
+        private void MoveWindow(object parameter)
+        {
+            base.DragMove(parameter);
+        }
+    }
+}

+ 109 - 0
PixiEditor/ViewModels/SaveFilePopupViewModel.cs

@@ -0,0 +1,109 @@
+using Microsoft.Win32;
+using PixiEditor.Helpers;
+using PixiEditor.Views;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+using System.Windows.Media;
+
+namespace PixiEditor.ViewModels
+{
+     class SaveFilePopupViewModel : ViewModelBase
+    {
+        public RelayCommand CloseButtonCommand { get; set; }
+        public RelayCommand DragMoveCommand { get; set; }
+        public RelayCommand ChoosePathCommand { get; set; }
+        public RelayCommand OkCommand { get; set; }
+
+
+        private string _pathButtonBorder = "#f08080";
+
+        public string PathButtonBorder
+        {
+            get { return _pathButtonBorder; }
+            set { if (_pathButtonBorder != value) { _pathButtonBorder = value; RaisePropertyChanged("PathButtonBorder"); } }
+        }
+
+
+        private bool _pathIsCorrect;
+
+        public bool PathIsCorrect
+        {
+            get { return _pathIsCorrect; }
+            set { if (_pathIsCorrect != value) { _pathIsCorrect = value; RaisePropertyChanged("PathIsCorrect"); } }
+        }
+
+
+        private string _filePath;
+
+        public string FilePath
+        {
+            get { return _filePath; }
+            set { if (_filePath != value) { _filePath = value; RaisePropertyChanged("FilePath"); } }
+        }
+
+        public SaveFilePopupViewModel()
+        {
+            CloseButtonCommand = new RelayCommand(CloseWindow);
+            DragMoveCommand = new RelayCommand(MoveWindow);
+            ChoosePathCommand = new RelayCommand(ChoosePath);
+            OkCommand = new RelayCommand(OkButton, CanClickOk);
+        }
+
+        /// <summary>
+        /// Command that handles Path choosing to save file
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void ChoosePath(object parameter)
+        {
+            SaveFileDialog path = new SaveFileDialog()
+            {
+                Title = "Export path",
+                CheckPathExists = true,
+                DefaultExt = "PNG Image (.png)|*.png",
+                Filter = "PNG Image (.png)|*.png"
+            };
+            if(path.ShowDialog() == true)
+            {
+                if (string.IsNullOrEmpty(path.FileName) == false)
+                {
+                    PathButtonBorder = "#b8f080";
+                    PathIsCorrect = true;
+                    FilePath = path.FileName;
+                }
+                else
+                {
+                    PathButtonBorder = "#f08080";
+                    PathIsCorrect = false;
+                }
+            }
+        }
+
+        private void CloseWindow(object parameter)
+        {
+            ((Window)parameter).DialogResult = false;
+            base.CloseButton(parameter);
+        }
+
+        private void MoveWindow(object parameter)
+        {
+            base.DragMove(parameter);
+        }
+
+        private void OkButton(object parameter)
+        {
+            ((Window)parameter).DialogResult = true;
+            base.CloseButton(parameter);
+        }
+
+        private bool CanClickOk(object property)
+        {
+            return PathIsCorrect == true;
+        }
+    }
+}

+ 38 - 0
PixiEditor/ViewModels/ViewModelBase.cs

@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Input;
+
+namespace PixiEditor.ViewModels
+{
+     class ViewModelBase : INotifyPropertyChanged
+    {
+        public event PropertyChangedEventHandler PropertyChanged = delegate { };
+
+        internal void RaisePropertyChanged(string property)
+        {
+            if (property != null)
+            {
+                PropertyChanged(this, new PropertyChangedEventArgs(property));
+            }
+        }
+
+        internal void CloseButton(object parameter)
+        {
+            ((Window)parameter).Close();
+        }
+
+        internal void DragMove(object parameter)
+        {
+            Window popup = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive);
+            if (Mouse.LeftButton == MouseButtonState.Pressed)
+            {
+                popup.DragMove();
+            }
+        }
+    }
+}

+ 297 - 0
PixiEditor/ViewModels/ViewModelMain.cs

@@ -0,0 +1,297 @@
+using Microsoft.Win32;
+using PixiEditor.Helpers;
+using PixiEditor.Models;
+using PixiEditor.Models.Enums;
+using PixiEditor.Models.Tools;
+using PixiEditor.Views;
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using Xceed.Wpf.Toolkit.Zoombox;
+
+namespace PixiEditor.ViewModels
+{
+    class ViewModelMain : ViewModelBase
+    {
+
+        private ObservableCollection<Layer> _layers;
+
+        public ObservableCollection<Layer> Layers
+        {
+            get { return _layers; }
+            set { if (_layers != value) { _layers = value;} }
+        }
+
+        public RelayCommand SelectToolCommand { get; set; } //Command that handles tool switching 
+        public RelayCommand GenerateDrawAreaCommand { get; set; } //Command that generates draw area
+        public RelayCommand MouseMoveOrClickCommand { get; set; } //Command that is used to draw
+        public RelayCommand SaveFileCommand { get; set; } //Command that is used to save file
+        public RelayCommand UndoCommand { get; set; }
+        public RelayCommand RedoCommand { get; set; }
+        public RelayCommand MouseUpCommand { get; set; }
+        public RelayCommand RecenterZoomboxCommand { get; set; }
+        public RelayCommand SendFeedbackCommand { get; set; }
+
+        private Layer _activeLayer;
+
+        public Layer ActiveLayer //Active drawing layer
+        {
+            get { return _activeLayer; }
+            set {
+                UndoManager.AddUndoChange("ActiveLayer", _activeLayer, value, "Layer Changed");
+                _activeLayer = value;
+                RefreshImage();
+                RaisePropertyChanged("ActiveLayer");
+            }
+        }
+
+        private double _mouseXonCanvas;
+
+        public double MouseXOnCanvas //Mouse X coordinate relative to canvas
+        {
+            get { return _mouseXonCanvas; }
+            set { _mouseXonCanvas = value;  RaisePropertyChanged("MouseXonCanvas"); }
+        }
+
+        private double _mouseYonCanvas;
+
+        public double MouseYOnCanvas //Mouse Y coordinate relative to canvas
+        {
+            get { return _mouseYonCanvas; }
+            set { _mouseYonCanvas = value; RaisePropertyChanged("MouseYonCanvas"); }
+        }
+
+
+        private Color _primaryColor = Colors.White;
+
+        public Color PrimaryColor //Primary color, hooked with left mouse button
+        {
+            get { return _primaryColor; }
+            set
+            {
+                if (_primaryColor != value)
+                {
+                   _primaryColor = value;
+                    RaisePropertyChanged("PrimaryColor");
+                }
+            }
+        }
+
+        private Color _secondaryColor = Colors.Black;
+
+        public Color SecondaryColor //Secondary color, hooked with right mouse button
+        {
+            get { return _secondaryColor; }
+            set { if (_secondaryColor != value) { _secondaryColor = value; RaisePropertyChanged("SecondaryColor"); } }
+        }
+       
+
+        private ToolType _selectedTool = ToolType.Pen;
+
+        public ToolType SelectedTool
+        {
+            get { return _selectedTool; }
+            set { if (_selectedTool != value) { _selectedTool = value; RaisePropertyChanged("SelectedTool"); } }
+        }
+
+
+        private int _toolSize = 1;
+
+        public int ToolSize
+        {
+            get { return _toolSize; }
+            set { if (_toolSize != value) { _toolSize = value; RaisePropertyChanged("ToolSize"); } }
+        }
+
+        private ToolSet primaryToolSet;
+
+        public ViewModelMain()
+        {
+            Layers = new ObservableCollection<Layer>();
+            SelectToolCommand = new RelayCommand(RecognizeTool);
+            GenerateDrawAreaCommand = new RelayCommand(GenerateDrawArea);
+            MouseMoveOrClickCommand = new RelayCommand(MouseMoveOrClick);
+            SaveFileCommand = new RelayCommand(SaveFile, CanSave);
+            UndoCommand = new RelayCommand(Undo, CanUndo);
+            RedoCommand = new RelayCommand(Redo, CanRedo);
+            MouseUpCommand = new RelayCommand(MouseUp);
+            RecenterZoomboxCommand = new RelayCommand(RecenterZoombox);
+            SendFeedbackCommand = new RelayCommand(SendFeedback);
+            primaryToolSet = new ToolSet();
+            UndoManager.SetMainRoot(this);
+        }
+
+        #region Undo/Redo
+        /// <summary>
+        /// Undo last action
+        /// </summary>
+        /// <param name="parameter"></param>
+        public void Undo(object parameter)
+        {
+            UndoManager.Undo();
+        }
+        /// <summary>
+        /// Returns true if undo can be done.
+        /// </summary>
+        /// <param name="property"></param>
+        /// <returns></returns>
+        private bool CanUndo(object property)
+        {
+            return UndoManager.CanUndo;
+        }
+        /// <summary>
+        /// Redo last action
+        /// </summary>
+        /// <param name="parameter"></param>
+        public void Redo(object parameter)
+        {
+            UndoManager.Redo();
+        }
+        /// <summary>
+        /// Returns true if redo can be done.
+        /// </summary>
+        /// <param name="property"></param>
+        /// <returns></returns>
+        private bool CanRedo(object property)
+        {
+            return UndoManager.CanRedo;
+        }
+        #endregion
+
+        /// <summary>
+        /// Recognizes selected tool from UI
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void RecognizeTool(object parameter)
+        {
+            ToolType tool = (ToolType)Enum.Parse(typeof(ToolType), parameter.ToString());
+            SelectedTool = tool;
+        }
+        /// <summary>
+        /// When mouse is up stops recording changes.
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void MouseUp(object parameter)
+        {
+            UndoManager.StopRecording();
+        }
+
+        /// <summary>
+        /// Method connected with command, it executes tool "activity"
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void MouseMoveOrClick(object parameter)
+        {
+            Color color;
+            Coordinates cords = new Coordinates((int)MouseXOnCanvas, (int)MouseYOnCanvas);
+            if (Mouse.LeftButton == MouseButtonState.Pressed)
+            {
+                color = PrimaryColor;
+            }
+            else if(Mouse.RightButton == MouseButtonState.Pressed)
+            {
+                color = SecondaryColor;
+
+            }
+            else
+            {
+                return;
+            }
+
+            if (SelectedTool != ToolType.ColorPicker)
+            {
+                primaryToolSet.UpdateCoordinates(cords);
+                primaryToolSet.ExecuteTool(ActiveLayer, cords, color, ToolSize,SelectedTool);
+                RefreshImage();
+            }
+            else
+            {
+                if (Mouse.LeftButton == MouseButtonState.Pressed)
+                {
+                    PrimaryColor = ToolSet.ColorPicker(ActiveLayer, cords);
+                }
+                else
+                {
+                    SecondaryColor = ToolSet.ColorPicker(ActiveLayer, cords);
+                }
+            }
+        }
+
+        private void RefreshImage()
+        {
+            //Jak nie będzie działać z layerami to tutaj szukaj błędu
+            if (ActiveLayer != null)
+            {
+                Layers[0].LayerImage.Source = ActiveLayer.LayerBitmap;
+            }
+        }
+
+        /// <summary>
+        /// Generates new Layer and sets it as active one
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void GenerateDrawArea(object parameter)
+        {
+            NewFileDialog newFile = new NewFileDialog();
+            if (newFile.ShowDialog() == true)
+            {
+                Layers.Clear();
+                Layers.Add(new Layer(newFile.Width, newFile.Height));
+                ActiveLayer = Layers[0];
+            }            
+        }
+        #region SaveFile
+        /// <summary>
+        /// Generates export dialog or saves directly if save data is known.
+        /// </summary>
+        /// <param name="parameter"></param>
+        private void SaveFile(object parameter)
+        {
+            if (Exporter._savePath == null)
+            {
+                Exporter.Export(FileType.PNG, ActiveLayer.LayerImage, new Size(ActiveLayer.Width, ActiveLayer.Height));
+            }
+            else
+            {
+                Exporter.ExportWithoutDialog(FileType.PNG, ActiveLayer.LayerImage);
+            }
+        }
+        /// <summary>
+        /// Returns true if file save is possible.
+        /// </summary>
+        /// <param name="property"></param>
+        /// <returns></returns>
+        private bool CanSave(object property)
+        {
+            return ActiveLayer != null;
+        }
+        #endregion
+
+        /// <summary>
+        /// For now, shows not implemented info, lol.
+        /// </summary>
+        /// <param name="parameter"></param>
+        public void RecenterZoombox(object parameter)
+        {
+            MessageBox.Show("This feature is not implemented yet.", "Feature not implemented", MessageBoxButton.OK, MessageBoxImage.Information);
+        }
+
+        public void SendFeedback(object parameter)
+        {
+            FeedbackMenuDialog feedbackMenuDialog = new FeedbackMenuDialog();
+            feedbackMenuDialog.ShowDialog();
+        }
+    }
+}

+ 46 - 0
PixiEditor/Views/FeedbackDialog.xaml

@@ -0,0 +1,46 @@
+<Window x:Class="PixiEditor.Views.FeedbackDialog"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PixiEditor.Views"
+        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+        xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours"
+        xmlns:vm="clr-namespace:PixiEditor.ViewModels"
+        mc:Ignorable="d"
+        Title="FeedbackDialog" WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" Height="600" Width="450" Name="feedbackDialog" DataContext="{DynamicResource FeedbackDialogViewModel}">
+    <Window.Resources>
+        <vm:FeedbackDialogViewModel x:Key="FeedbackDialogViewModel"/>
+    </Window.Resources>
+    <Grid Background="#303030">
+        <Grid.RowDefinitions>
+            <RowDefinition/>
+            <RowDefinition Height="25*"/>
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0" Background="#FF2C2C2C">
+            <i:Interaction.Triggers>
+                <i:EventTrigger EventName="MouseDown">
+                    <i:InvokeCommandAction Command="{Binding DragMoveCommand}"/>
+                </i:EventTrigger>
+            </i:Interaction.Triggers>
+            <Button Width="20" Height="20" VerticalAlignment="Top" HorizontalAlignment="Right" BorderThickness="0" Command="{Binding CloseButtonCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
+                <Button.Background>
+                    <ImageBrush ImageSource="/PixiEditor;component/Images/Cross.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+        </Grid>
+        <StackPanel Grid.Row="2">
+        <Label Height="60" Width="200" VerticalAlignment="Top" Margin="0,40,0,0" Content="Feedback" FontSize="36" Foreground="Snow" HorizontalContentAlignment="Center"/>
+            <TextBox Style="{StaticResource DarkTextBoxStyle}" FontSize="22" Height="210" Width="365" Margin="0,10,0,0" Text="{Binding EmailBody, Mode=TwoWay}">
+                <i:Interaction.Behaviors>
+                <behaviors:HintTextBehavior Hint="I'd love to hear your feedback!"/>
+                </i:Interaction.Behaviors>
+            </TextBox>
+            <DockPanel Width="365">
+            <Label Height="42" Width="120" HorizontalAlignment="Left" Margin="0,20,0,0" Foreground="Snow" FontSize="22" Content="Your email"/>
+                <TextBox Height="35" Width="244" FontSize="20" VerticalAlignment="Bottom" Margin="-0,0,0,5" Style="{StaticResource DarkTextBoxStyle}" Text="{Binding MailFrom, Mode=TwoWay}"/>
+            </DockPanel>
+        </StackPanel>
+        <Button Style="{StaticResource DarkRoundButton}" Grid.Row="1" Height="35" Width="70" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="10" Content="Send" Command="{Binding SendButtonCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
+    </Grid>
+</Window>

+ 27 - 0
PixiEditor/Views/FeedbackDialog.xaml.cs

@@ -0,0 +1,27 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace PixiEditor.Views
+{
+    /// <summary>
+    /// Interaction logic for FeedbackDialog.xaml
+    /// </summary>
+    public partial class FeedbackDialog : Window
+    {
+        public FeedbackDialog()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 20 - 0
PixiEditor/Views/MainDrawingPanel.xaml

@@ -0,0 +1,20 @@
+<UserControl x:Class="PixiEditor.Views.MainDrawingPanel"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:PixiEditor.Views"
+             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
+             xmlns:helpers="clr-namespace:PixiEditor.Helpers"
+             xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
+             mc:Ignorable="d" 
+             d:DesignHeight="450" d:DesignWidth="800" x:Name="mainDrawingPanel">
+    <xctk:Zoombox IsAnimated="False" Name="Zoombox" KeepContentInBounds="True" Loaded="Zoombox_Loaded">
+        <i:Interaction.Triggers>
+            <i:EventTrigger EventName="MouseMove">
+                <i:InvokeCommandAction Command="{Binding MouseMoveCommand, ElementName=mainDrawingPanel, Mode=OneWay}"/>
+            </i:EventTrigger>
+        </i:Interaction.Triggers>
+        <ContentPresenter Content="{Binding Item, ElementName=mainDrawingPanel}"/>
+    </xctk:Zoombox>
+</UserControl>

+ 99 - 0
PixiEditor/Views/MainDrawingPanel.xaml.cs

@@ -0,0 +1,99 @@
+using PixiEditor.Models;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Xceed.Wpf.Toolkit.Zoombox;
+
+namespace PixiEditor.Views
+{
+    /// <summary>
+    /// Interaction logic for MainDrawingPanel.xaml
+    /// </summary>
+    public partial class MainDrawingPanel : UserControl
+    {
+        public MainDrawingPanel()
+        {
+            InitializeComponent();
+        }
+
+
+
+        public double MouseX
+        {
+            get { return (double)GetValue(MouseXProperty); }
+            set { SetValue(MouseXProperty, value);}
+        }
+
+        // Using a DependencyProperty as the backing store for MouseX.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty MouseXProperty =
+            DependencyProperty.Register("MouseX", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(null));
+
+        public double MouseY
+        {
+            get { return (double)GetValue(MouseYProperty); }
+            set { SetValue(MouseYProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MouseX.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty MouseYProperty =
+            DependencyProperty.Register("MouseY", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(null));
+
+
+        public ICommand MouseMoveCommand
+        {
+            get { return (ICommand)GetValue(MouseMoveCommandProperty); }
+            set { SetValue(MouseMoveCommandProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for MouseMoveCommand.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty MouseMoveCommandProperty =
+            DependencyProperty.Register("MouseMoveCommand", typeof(ICommand), typeof(MainDrawingPanel), new PropertyMetadata(null));
+
+
+
+        public bool CenterOnStart
+        {
+            get { return (bool)GetValue(CenterOnStartProperty); }
+            set { SetValue(CenterOnStartProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for CenterOnStart.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty CenterOnStartProperty =
+            DependencyProperty.Register("CenterOnStart", typeof(bool), typeof(MainDrawingPanel), new PropertyMetadata(false));
+
+
+
+        public object Item
+        {
+            get { return (object)GetValue(ItemProperty); }
+            set { SetValue(ItemProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for Item.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty ItemProperty =
+            DependencyProperty.Register("Item", typeof(object), typeof(MainDrawingPanel), new PropertyMetadata(0));
+
+
+
+
+        private void Zoombox_Loaded(object sender, RoutedEventArgs e)
+        {
+            if(CenterOnStart == true)
+            {
+                ((Zoombox)sender).CenterContent();
+            }
+        }
+    }
+}

+ 206 - 0
PixiEditor/Views/MainWindow.xaml

@@ -0,0 +1,206 @@
+<Window x:Class="PixiEditor.MainWindow" MinHeight="1000" MinWidth="1100"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PixiEditor"
+        xmlns:vm="clr-namespace:PixiEditor.ViewModels"
+        xmlns:vws="clr-namespace:PixiEditor.Views"
+        xmlns:helpers="clr-namespace:PixiEditor.Helpers"
+        xmlns:behaviors="clr-namespace:PixiEditor.Helpers.Behaviours"
+        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
+        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
+        mc:Ignorable="d"
+        Title="Pixi" Height="1000" Width="1600" Background="#FF252424" WindowStartupLocation="CenterScreen" WindowState="Maximized" DataContext="{DynamicResource ViewModelMain}">
+    <Window.Resources>
+        <vm:ViewModelMain x:Key="ViewModelMain"/>
+        <BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
+        <helpers:ToolSizeToIntConverter x:Key="ToolSizeToIntConverter"/>
+    </Window.Resources>
+    <Window.InputBindings>
+        <KeyBinding 
+            Modifiers="Ctrl" 
+            Key="N"
+            Command="{Binding GenerateDrawAreaCommand}"/>
+        <KeyBinding
+            Modifiers="Ctrl"
+            Key="S"
+            Command="{Binding SaveFileCommand}"/>
+        <KeyBinding
+            Modifiers="Ctrl"
+            Key="Z"
+            Command="{Binding UndoCommand}"/>
+        <KeyBinding 
+            Modifiers="Ctrl"
+            Key="Y"
+            Command="{Binding RedoCommand}"/>
+        <KeyBinding            
+            Key="B"
+            Command="{Binding SelectToolCommand}"
+            CommandParameter="Pen"/>
+        <KeyBinding
+            Key="G"
+            Command="{Binding SelectToolCommand}"
+            CommandParameter="Bucket"/>
+        <KeyBinding
+            Key="L"
+            Command="{Binding SelectToolCommand}"
+            CommandParameter="Line"/>
+        <KeyBinding
+            Key="C"
+            Command="{Binding SelectToolCommand}"
+            CommandParameter="Circle"/>
+        <KeyBinding Key="R"
+                    Command="{Binding SelectToolCommand}"
+                    CommandParameter="Rectangle"/>
+        <KeyBinding Key="O"
+                    Command="{Binding SelectToolCommand}"
+                    CommandParameter="ColorPicker"/>
+        <KeyBinding Key="E"
+                    Command="{Binding SelectToolCommand}"
+                    CommandParameter="Earser"/>
+        <KeyBinding Key="U"
+                    Command="{Binding SelectToolCommand}"
+                    CommandParameter="Lighten"/>
+
+
+    </Window.InputBindings>
+    <Grid>
+        <Grid.ColumnDefinitions>
+            <ColumnDefinition Width="70*"/>
+            <ColumnDefinition Width="1420*"/>
+            <ColumnDefinition Width="110*"/>
+        </Grid.ColumnDefinitions>
+        <Grid.RowDefinitions>
+            <RowDefinition Height="30*"/>
+            <RowDefinition Height="908*"/>
+            <RowDefinition Height="30*"/>
+        </Grid.RowDefinitions>
+
+        <Border Grid.ColumnSpan="3" Background="#FF363434" Grid.Row="0" Height="30"/>
+        <WrapPanel Grid.ColumnSpan="2" Grid.RowSpan="2" Panel.ZIndex="100">
+            <vws:MenuButton Text="File" Margin="0,0,-140,0">
+                <vws:MenuButton.Item>
+                    <StackPanel>
+                        <Button Style="{StaticResource MenuInsideButtonStyle}" Content="New" Command="{Binding GenerateDrawAreaCommand}"/>
+                        <Button Style="{StaticResource MenuInsideButtonStyle}" Content="Save" Command="{Binding SaveFileCommand}"/>
+                    </StackPanel>
+                </vws:MenuButton.Item>
+            </vws:MenuButton>
+            <vws:MenuButton Text="Edit" Margin="0,0,-140,0">
+                <vws:MenuButton.Item>
+                    <StackPanel>
+                        <Button Style="{StaticResource MenuInsideButtonStyle}" Content="Undo" Command="{Binding UndoCommand}"/>
+                        <Button Style="{StaticResource MenuInsideButtonStyle}" Content="Redo" Command="{Binding RedoCommand}"/>
+                    </StackPanel>
+                </vws:MenuButton.Item>
+            </vws:MenuButton>
+
+            <vws:MenuButton Text="View" Margin="0,0,-140,0">
+                <vws:MenuButton.Item>
+                    <StackPanel>
+                        <Button Style="{StaticResource MenuInsideButtonStyle}" Content="Recenter" Command="{Binding RecenterZoomboxCommand}" CommandParameter="{Binding ElementName=Zoombox}"/>
+                    </StackPanel>
+                </vws:MenuButton.Item>
+            </vws:MenuButton>
+        </WrapPanel>
+        <Grid Grid.Column="1" Grid.Row="1" Background="DimGray" Margin="0,5,0,0">
+            <Grid>
+                <vws:MainDrawingPanel CenterOnStart="True">
+                    <vws:MainDrawingPanel.Item>
+                        <Canvas Width="{Binding ActiveLayer.Width}" Height="{Binding ActiveLayer.Height}" VerticalAlignment="Center" HorizontalAlignment="Center">
+                            <i:Interaction.Triggers>
+                                <i:EventTrigger EventName="MouseMove">
+                                    <i:InvokeCommandAction Command="{Binding MouseMoveOrClickCommand}"/>
+                                </i:EventTrigger>
+                                <i:EventTrigger EventName="MouseDown">
+                                    <i:InvokeCommandAction Command="{Binding MouseMoveOrClickCommand}"/>
+                                </i:EventTrigger>
+                                <i:EventTrigger EventName="MouseUp">
+                                    <i:InvokeCommandAction Command="{Binding MouseUpCommand}"/>
+                                </i:EventTrigger>
+                            </i:Interaction.Triggers>
+                            <i:Interaction.Behaviors>
+                                <behaviors:MouseBehaviour MouseX="{Binding MouseXOnCanvas, Mode=OneWayToSource}" MouseY="{Binding MouseYOnCanvas, Mode=OneWayToSource}"/>
+                            </i:Interaction.Behaviors>
+                            <Image Source="/Images/transparent bg.png" Height="{Binding ActiveLayer.Height}" Width="{Binding ActiveLayer.Width}" Opacity="0.2" Stretch="UniformToFill"/>
+                            <ItemsControl ItemsSource="{Binding Layers}">
+                                <ItemsControl.ItemTemplate>
+                                    <DataTemplate>
+                                        <ContentControl Content="{Binding LayerImage}"/>
+                                    </DataTemplate>
+                                </ItemsControl.ItemTemplate>
+                            </ItemsControl>
+
+
+                        </Canvas>
+                    </vws:MainDrawingPanel.Item>
+                </vws:MainDrawingPanel>
+            </Grid>
+        </Grid>
+
+        <StackPanel Grid.Row="1" Grid.Column="0" Margin="0,5,5,0" Background="#363434" Grid.RowSpan="2">
+            <TextBox Style="{StaticResource DarkTextBoxStyle}" Margin="0,10,0,0" Text="{Binding ToolSize, Mode=TwoWay,Converter={StaticResource ToolSizeToIntConverter}}" TextAlignment="Center" MaxLength="4">
+                <i:Interaction.Behaviors>
+                    <behaviors:TextBoxNumericFinisherBehavior/>
+                </i:Interaction.Behaviors>
+            </TextBox>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Pen">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Pen Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Bucket">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Bucket Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Line">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Line Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Circle">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Circle Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Rectangle">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Rectangle Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="ColorPicker">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Pipette Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Earser">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Earser Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+            <Button Style="{StaticResource ToolButtonStyle}" Command="{Binding SelectToolCommand, Mode=OneWay}" CommandParameter="Lighten">
+                <Button.Background>
+                    <ImageBrush ImageSource="/Images/Lighten Image.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+        </StackPanel>
+
+        <Grid VerticalAlignment="Bottom" HorizontalAlignment="Center" Width="60" Grid.Column="0" Grid.Row="1" Margin="0,0,0,0" Height="65">
+            <Rectangle Height="40" Width="40" HorizontalAlignment="Left" VerticalAlignment="Top" Stroke="Black" StrokeThickness="1">
+                <Rectangle.Fill>
+                    <SolidColorBrush Color="{Binding PrimaryColor, Mode=OneWay}"/>
+                </Rectangle.Fill>
+            </Rectangle>
+            <xctk:ColorPicker Width="40" Height="40" VerticalAlignment="Top" HorizontalAlignment="Left" UsingAlphaChannel="True" AvailableColorsSortingMode="Alphabetical" ShowDropDownButton="False" Background="Transparent" BorderThickness="0" ShowRecentColors="True" SelectedColor="{Binding PrimaryColor, Mode=TwoWay}"></xctk:ColorPicker>
+            <Rectangle Height="40" Width="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" Stroke="Black" StrokeThickness="1" Margin="0,0,4,5">
+                <Rectangle.Fill>
+                    <SolidColorBrush Color="{Binding SecondaryColor, Mode=OneWay}"/>
+                </Rectangle.Fill>
+            </Rectangle>
+            <xctk:ColorPicker Width="40" Height="40" HorizontalAlignment="Right" VerticalAlignment="Bottom" UsingAlphaChannel="True" AvailableColorsSortingMode="Alphabetical" ShowDropDownButton="False" Background="Transparent" BorderThickness="0" ShowRecentColors="True" Margin="0,0,4,5" SelectedColor="{Binding SecondaryColor, Mode=TwoWay}"/>
+        </Grid>
+
+    </Grid>
+</Window>

+ 30 - 0
PixiEditor/Views/MainWindow.xaml.cs

@@ -0,0 +1,30 @@
+using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using Xceed.Wpf.Toolkit.Core.Input;
+
+namespace PixiEditor
+{
+    /// <summary>
+    /// Interaction logic for MainWindow.xaml
+    /// </summary>
+    public partial class MainWindow : Window
+    {
+        public MainWindow()
+        {
+            InitializeComponent();
+        }
+    }
+}

+ 50 - 0
PixiEditor/Views/MenuButton.xaml

@@ -0,0 +1,50 @@
+<UserControl x:Class="PixiEditor.Views.MenuButton"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:PixiEditor.Views"
+             xmlns:vm="clr-namespace:PixiEditor.ViewModels"
+             xmlns:helpers="clr-namespace:PixiEditor.Helpers"
+             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+             mc:Ignorable="d" 
+             d:DesignHeight="330" d:DesignWidth="200" x:Name="menuButton" DataContext="{DynamicResource MenuButtonViewModel}">
+    <UserControl.Resources>
+        <vm:MenuButtonViewModel x:Key="MenuButtonViewModel"/>
+        <Style TargetType="ListViewItem">
+            <Style.Resources>
+                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Transparent"/>
+                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
+
+            </Style.Resources>
+        </Style>
+    </UserControl.Resources>
+
+    <StackPanel Name="MainStackPanel">
+        <Button Content="{Binding ElementName=menuButton,Path=Text}" Style="{StaticResource MenuButton}" HorizontalAlignment="Left" Command="{Binding OpenListViewCommand}"/>
+        <ListView Visibility="{Binding ListViewVisibility}" Style="{StaticResource MenuListViewStyle}">
+            <ListView.ItemContainerStyle>
+                <Style TargetType="{x:Type ListViewItem}">
+                    <Setter Property="Background" Value="Transparent"/>
+                    <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
+                    <Setter Property="Template">
+                        <Setter.Value>
+                            <ControlTemplate TargetType="{x:Type ListViewItem}">
+                                <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="Transparent"  Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
+                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+                                </Border>
+                                <ControlTemplate.Triggers>
+                                    <Trigger Property="IsMouseOver" Value="True">
+                                        <Setter Property="BorderThickness" Value="1" />
+                                        <Setter Property="BorderBrush" Value="Transparent" />
+                                    </Trigger>
+                                </ControlTemplate.Triggers>
+                            </ControlTemplate>
+                        </Setter.Value>
+                    </Setter>
+                </Style>
+            </ListView.ItemContainerStyle>
+            <ContentPresenter Content="{Binding Item, ElementName=menuButton}"/>
+        </ListView>
+    </StackPanel>
+</UserControl>

+ 55 - 0
PixiEditor/Views/MenuButton.xaml.cs

@@ -0,0 +1,55 @@
+using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PixiEditor.Views
+{
+    /// <summary>
+    /// Interaction logic for MenuButton.xaml
+    /// </summary>
+    public partial class MenuButton : UserControl
+    {
+        MenuButtonViewModel dc = new MenuButtonViewModel();
+        public MenuButton()
+        {
+            InitializeComponent();
+            this.DataContext = dc;
+        }
+
+        public static readonly DependencyProperty MenuButtonTextProperty = DependencyProperty.Register("Text", typeof(String), typeof(MenuButton), new UIPropertyMetadata(string.Empty));
+        public String Text
+        {
+            get { return (string)GetValue(MenuButtonTextProperty); }
+            set { SetValue(MenuButtonTextProperty, value); }
+        }
+
+
+
+        public object Item
+        {
+            get { return GetValue(ItemProperty); }
+            set { SetValue(ItemProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for Item.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty ItemProperty =
+            DependencyProperty.Register("Item", typeof(object), typeof(MenuButton), new PropertyMetadata(null));
+
+        protected override void OnIsKeyboardFocusWithinChanged(DependencyPropertyChangedEventArgs e)
+        {
+            dc.CloseListViewCommand.Execute(null);
+        }
+    }
+}

+ 52 - 0
PixiEditor/Views/NewFilePopup.xaml

@@ -0,0 +1,52 @@
+<Window x:Class="PixiEditor.Views.NewFilePopup"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
+             xmlns:local="clr-namespace:PixiEditor.Views"
+             xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+             xmlns:vm="clr-namespace:PixiEditor.ViewModels"
+             xmlns:helpers="clr-namespace:PixiEditor.Helpers.Behaviours"
+             mc:Ignorable="d" 
+             d:DesignHeight="600" d:DesignWidth="450" DataContext="{DynamicResource NewFileMenuViewModel}" WindowStyle="None" WindowStartupLocation="CenterScreen" ResizeMode="NoResize" Height="600" Width="450" Name="newFilePopup">
+    <Window.Resources>
+        <vm:NewFileMenuViewModel x:Key="NewFileMenuViewModel"/>
+    </Window.Resources>
+    <Grid Background="#303030">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="25*"/>
+            <RowDefinition Height="577*"/>
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0" Background="#FF2C2C2C">
+            <i:Interaction.Triggers>
+                <i:EventTrigger EventName="MouseDown">
+                    <i:InvokeCommandAction Command="{Binding DragMoveCommand}"/>
+                </i:EventTrigger>
+            </i:Interaction.Triggers>
+            <Button Width="20" Height="20" VerticalAlignment="Top" HorizontalAlignment="Right" BorderThickness="0" Command="{Binding CloseCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
+            <Button.Background>
+                <ImageBrush ImageSource="/PixiEditor;component/Images/Cross.png" Stretch="Uniform"/>
+            </Button.Background>
+        </Button>
+        </Grid>
+        <StackPanel HorizontalAlignment="Center" Margin="0,50,0,0" Background="#FF2E2E2E" VerticalAlignment="Top" Grid.Row="1" Width="350" Height="150">
+            <DockPanel Margin="50,35,0,0">
+            <TextBlock Height="30" Foreground="Snow" Text="Height:" TextAlignment="Center" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                <TextBox Height="30" Width="150" Style="{StaticResource DarkTextBoxStyle}" FontSize="16" HorizontalAlignment="Left" TextAlignment="Center" Margin="5,0,0,0" Text="{Binding ElementName=newFilePopup, Path=FileHeight, Mode=TwoWay}" MaxLength="4">
+                    <i:Interaction.Behaviors>
+                        <helpers:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9./-]+$" MaxLength="4"/>
+                    </i:Interaction.Behaviors>
+                </TextBox>
+            </DockPanel>
+            <DockPanel Margin="50,10,0,0">
+                <TextBlock Height="30" Foreground="Snow" Text="Width:" TextAlignment="Center" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
+                <TextBox Height="30" Width="150" Style="{StaticResource DarkTextBoxStyle}" FontSize="16" HorizontalAlignment="Left" Margin="10,0,0,0" TextAlignment="Center" Text="{Binding ElementName=newFilePopup, Path=FileWidth, Mode=TwoWay}" MaxLength="4">
+                    <i:Interaction.Behaviors>
+                        <helpers:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9./-]+$" MaxLength="4"/>
+                    </i:Interaction.Behaviors>
+                </TextBox>
+            </DockPanel>
+        </StackPanel>
+        <Button VerticalAlignment="Bottom" HorizontalAlignment="Right" FontSize="20" Height="30" Width="60" Style="{StaticResource DarkRoundButton}" Content="OK" Margin="0,0,10,10" Grid.Row="1" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
+    </Grid>
+</Window>

+ 57 - 0
PixiEditor/Views/NewFilePopup.xaml.cs

@@ -0,0 +1,57 @@
+using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+
+namespace PixiEditor.Views
+{
+    /// <summary>
+    /// Interaction logic for NewFilePopup.xaml
+    /// </summary>
+    public partial class NewFilePopup : Window
+    {
+        public NewFilePopup()
+        {
+            InitializeComponent();
+        }
+
+
+
+        public int FileHeight
+        {
+            get { return (int)GetValue(FileHeightProperty); }
+            set { SetValue(FileHeightProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for FileHeight.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty FileHeightProperty =
+            DependencyProperty.Register("FileHeight", typeof(int), typeof(NewFilePopup), new PropertyMetadata(16));
+
+
+
+        public int FileWidth
+        {
+            get { return (int)GetValue(FileWidthProperty); }
+            set { SetValue(FileWidthProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for FileWidth.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty FileWidthProperty =
+            DependencyProperty.Register("FileWidth", typeof(int), typeof(NewFilePopup), new PropertyMetadata(16));
+
+
+
+
+    }
+}

+ 47 - 0
PixiEditor/Views/SaveFilePopup.xaml

@@ -0,0 +1,47 @@
+<Window x:Class="PixiEditor.Views.SaveFilePopup"
+        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+        xmlns:local="clr-namespace:PixiEditor.Views"
+        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
+        xmlns:vm="clr-namespace:PixiEditor.ViewModels"
+        xmlns:helpers="clr-namespace:PixiEditor.Helpers.Behaviours"
+        mc:Ignorable="d"
+        Title="SaveFilePopup" Height="250" Width="400" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen"  Name="saveFilePopup">
+    <Grid Background="#303030">
+        <Grid.RowDefinitions>
+            <RowDefinition Height="20*"/>
+            <RowDefinition Height="229*"/>
+        </Grid.RowDefinitions>
+        <Grid Grid.Row="0" Background="#FF2C2C2C">
+            <i:Interaction.Triggers>
+                <i:EventTrigger EventName="MouseDown">
+                    <i:InvokeCommandAction Command="{Binding DragMoveCommand}"/>
+                </i:EventTrigger>
+            </i:Interaction.Triggers>
+            <Button Width="20" Height="20" VerticalAlignment="Top" HorizontalAlignment="Right" BorderThickness="0" Command="{Binding CloseButtonCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}">
+                <Button.Background>
+                    <ImageBrush ImageSource="/PixiEditor;component/Images/Cross.png" Stretch="Uniform"/>
+                </Button.Background>
+            </Button>
+        </Grid>
+        <TextBlock Grid.Row="1" Height="30" Width="120" Foreground="Snow" VerticalAlignment="Top" HorizontalAlignment="Center" Text="File settings" TextAlignment="Center" FontSize="20"/>
+        <DockPanel Grid.Row="1" Height="70" Width="320" Margin="0,0,0,100" Background="#FF2E2E2E">
+            <TextBlock Foreground="Snow" Width="40" Height="40" HorizontalAlignment="Left" Margin="50,0,0,0" Text="Width:" TextAlignment="Center" Padding="0,11.5,0,0"/>
+            <TextBox Style="{StaticResource DarkTextBoxStyle}" Width="70" Height="20" HorizontalAlignment="Left" Margin="5,0,0,0" Text="{Binding ElementName=saveFilePopup, Path=SaveWidth, Mode=TwoWay}">
+                <i:Interaction.Behaviors>
+                    <helpers:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9./-]+$" MaxLength="4"/>
+                </i:Interaction.Behaviors>
+            </TextBox>
+            <TextBlock Foreground="Snow" Width="40" Height="40"  HorizontalAlignment="Left" Margin="5,0,0,0" Text="Height:" TextAlignment="Center" Padding="0,11.5,0,0"/>
+            <TextBox Style="{StaticResource DarkTextBoxStyle}" Width="70" Height="20" HorizontalAlignment="Left" Margin="5,0,0,0" Text="{Binding ElementName=saveFilePopup, Path=SaveHeight,Mode=TwoWay}">
+                <i:Interaction.Behaviors>
+                    <helpers:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9./-]+$" MaxLength="4"/>
+                </i:Interaction.Behaviors>
+            </TextBox>
+        </DockPanel>
+        <Button Grid.Row="1" Foreground="Snow" Height="40" Width="160" Margin="0,50,0,0" Content="Path" Background="#303030" BorderBrush="{Binding PathButtonBorder}" Command="{Binding ChoosePathCommand}"/>
+        <Button Grid.Row="1" Height="30" Width="60" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="10" Style="{StaticResource DarkRoundButton}" Content="OK" Command="{Binding OkCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"/>
+    </Grid>
+</Window>

+ 62 - 0
PixiEditor/Views/SaveFilePopup.xaml.cs

@@ -0,0 +1,62 @@
+using PixiEditor.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows;
+using System.Windows.Controls;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Input;
+using System.Windows.Media;
+using System.Windows.Media.Imaging;
+using System.Windows.Shapes;
+
+namespace PixiEditor.Views
+{
+    /// <summary>
+    /// Interaction logic for SaveFilePopup.xaml
+    /// </summary>
+    public partial class SaveFilePopup : Window
+    {
+        SaveFilePopupViewModel dataContext = new SaveFilePopupViewModel();
+        public SaveFilePopup()
+        {
+            InitializeComponent();
+            this.DataContext = dataContext;
+        }
+
+
+
+        public int SaveWidth
+        {
+            get { return (int)GetValue(SaveWidthProperty); }
+            set { SetValue(SaveWidthProperty, value); }
+        }
+
+
+
+        public int SaveHeight
+        {
+            get { return (int)GetValue(SaveHeightProperty); }
+            set { SetValue(SaveHeightProperty, value); }
+        }
+
+        // Using a DependencyProperty as the backing store for SaveHeight.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty SaveHeightProperty =
+            DependencyProperty.Register("SaveHeight", typeof(int), typeof(SaveFilePopup), new PropertyMetadata(32));
+
+
+
+        // Using a DependencyProperty as the backing store for SaveWidth.  This enables animation, styling, binding, etc...
+        public static readonly DependencyProperty SaveWidthProperty =
+            DependencyProperty.Register("SaveWidth", typeof(int), typeof(SaveFilePopup), new PropertyMetadata(32));
+
+        public string SavePath
+        {
+            get { return dataContext.FilePath; }
+            set { dataContext.FilePath = value; }
+        }
+    }
+}

+ 6 - 0
PixiEditor/packages.config

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+  <package id="Expression.Blend.Sdk" version="1.0.2" targetFramework="net461" />
+  <package id="Extended.Wpf.Toolkit" version="3.4.0" targetFramework="net461" />
+  <package id="WriteableBitmapEx" version="1.5.1.0" targetFramework="net461" />
+</packages>